xviz企业级应用(自动驾驶项目)

618 阅读7分钟

基本概念

  • xviz数据解析分析流程

image.png

它可以被拆分为两部分,即XVIZ客户端和XVIZ服务端。

  • XVIZ服务端:这部分负责读取源数据(如传感器原始数据),将其转换成XVIZ格式,并发送给客户端。一般来说,这可能会涉及大量的处理工作,比如处理雷达、激光雷达(LiDAR)以及摄像头等设备的数据。
  • XVIZ客户端:接收服务端发来的XVIZ数据,并将其可视化。这是通过解析数据并将其在一个图形界面上呈现出来完成的。

streetscape.gl

streetscape.gl 是一个基于deck.gl 的开源软件库,专为自动驾驶数据可视化设计。它使用了XVIZ作为其数据输入格式,这意味着它可以直接从XVIZ客户端接收数据。事实上,streetscape.gl 可以被看作是一个特定的XVIZ客户端,其使用React和WebGL技术进行数据的渲染和展示。

  • XVIZ客户端和服务端一起定义了一个用于自动驾驶数据的标准格式,并提供了与这种格式交互的机制
  • streetscape.gl 是一个具体的XVIZ客户端实现,它使用React技术,并可以直接处理XVIZ服务端传输过来的数据进行可视化。

企业级应用解析

在处理XVIZ数据的过程中,通常会涉及到几个重要的步骤:Formatter(格式化)、Parser(解析)和Builder(构建)。以下是这些步骤的基本概念:

  1. Formatter:Formatter负责将输入数据转换成XVIZ可以接受的格式。可能的输入数据类型包括JSON、二进制数据等。
  2. Parser:Parser接收Formatter处理过的数据,并将其解析为一种可以用来绘制图形或进行其他操作的形式。例如,它可能会将JSON数据解析为JavaScript对象。
  3. Builder:Builder使用Parser解析过的数据来创建一个或多个XVIZ流。每个流都包含了一系列的时间序列数据元素,如3D模型的顶点、道路标记的位置等。这些数据元素总共描述了一个特定的场景或一段时间的状态。

以上三个步骤往往在一个数据管道中串联执行。对于实时环境,这个过程可能会不断地重复,以便持续更新和绘制新的数据。

xviz与WebSocket

  1. 客户端向服务端发起WebSocket连接请求,请求中包含WebSocket协议头部信息,如UpgradeConnection等字段。
  2. 服务端接收到连接请求后,根据请求头部信息进行握手操作。握手过程包括验证请求头、生成响应头、发送响应头等步骤,其目的是确保客户端和服务端都能支持WebSocket协议,并且双方可以开始通信。
  3. 握手成功之后,服务端和客户端就可以通过WebSocket通道进行双向数据传输。客户端可以使用JavaScript编写WebSocket客户端代码,通过调用WebSocket API来与服务端建立连接、发送和接收数据。服务端则可以使用 Node.js提供的WebSocket模块来实现WebSocket服务端代码,处理客户端的连接、数据传输等操作。
  4. 在xviz中,服务端通过WebSocket传递序列化后的JSON格式的消息给客户端,消息格式基于xviz的规范定义。客户端可以解析这些消息并将其渲染成3D场景。

传感器数据 -> xviz数据流

const WebSocket = require('ws');
const { XVIZ_MESSAGE_NAMESPACE } = require('@xviz/io');

// 创建WebSocket服务器并监听指定端口
const wss = new WebSocket.Server({ port: 8081 });

// 当WebSocket连接建立时,打印调试信息
wss.on('connection', function connection(ws) {
  console.log('WebSocket client connected.');
  
  // 当收到消息时,解析JSON并构造XVIZFrame实例,并发送XVIZ数据流到客户端
  ws.on('message', function incoming(message) {
    const data = JSON.parse(message);
    
    // 构造XVIZFrame实例,包含传感器数据和时间戳等信息
    const frame = new XVIZFrame({
      updates: [
        {
          timestamp: Date.now(),
          poses: {}, // 包含车辆位置等信息
          primitives: [] // 包含其他对象的位置、方向、尺寸等信息
        }
      ]
    });
    
    // 将XVIZFrame实例序列化为JSON格式,并通过WebSocket通道发送给客户端
    ws.send(JSON.stringify(frame));
  });
});

在上面的示例中,我们首先创建了一个WebSocket.Server实例,用于监听8081端口并接收来自客户端的WebSocket连接。在每个WebSocket连接上,我们定义了一个回调函数,用于处理传感器数据消息。

当收到来自客户端的传感器数据消息时,我们将其解析为JSON格式,并使用XVIZFrame构造函数构造一个XVIZFrame对象,其中包含传感器数据和时间戳等信息。然后,我们将XVIZFrame实例序列化为JSON格式,并通过WebSocket通道发送给客户端。

总之,在Node.js中使用WebSocket服务模块接收传感器数据并将其转换为xviz数据流非常简单,只需要使用WebSocket模块创建WebSocket服务器,并监听客户端的连接请求即可。在连接建立后,我们可以使用WebSocket模块提供的API实现双向数据传输,并通过xviz提供的API进行数据解析和处理。

xviz数据-> 3d渲染

具体过程如下:

  1. 服务端根据xviz的规范定义将自动驾驶车辆的数据转换为JSON格式,并对其进行序列化。
  2. 服务端将序列化后的JSON格式数据通过WebSocket通道传输到客户端。
  3. 客户端接收到服务端发送的JSON格式数据后,解析JSON并使用xviz提供的JavaScript API对其进行处理,包括解压、解码、解密等操作,得到xviz数据流。
  4. 客户端将xviz数据流渲染成3D场景。具体来说,客户端使用xviz提供的三维坐标系、属性和样式等信息,创建模型、图层和视角等元素,并在场景中按照时间轴展示这些元素的变化。
  5. 如果有新的数据可用,则服务端会持续向客户端发送JSON格式数据,客户端会将其渲染成新的3D场景,并在原场景上进行增量更新或替换。

总之,在xviz中,服务端通过WebSocket传递序列化后的JSON格式的数据给客户端,客户端可以解析和渲染这些数据以实现自动驾驶车辆的可视化。由于xviz的消息格式和API是按照一定规范定义的,因此不同的xviz实现之间可以互相兼容,并且可以灵活适应不同的数据源和场景

整体流程案例解析:

一个具体的xviz案例是,使用xviz将自动驾驶汽车的数据转换为可视化的3D场景。

  1. 收集汽车的传感器数据,例如GPS、雷达、摄像头等。
  2. 将传感器数据发送到xviz服务端,服务端使用Node.js编写的WebSocket服务模块接收数据并将其转换为xviz数据流。
  3. xviz服务端对传感器数据进行解析、压缩、编码和加密等操作,并将处理后的xviz数据流以JSON格式序列化,并通过WebSocket通道传输给客户端。
  4. 前端浏览器作为客户端接收到JSON格式的xviz数据流,并使用xviz提供的JavaScript API解析JSON并渲染成3D场景。
  5. 在场景中显示自动驾驶汽车的位置、速度、方向等信息,并根据汽车的传感器数据更新场景中的元素和属性。
  6. 通过交互控件、动画效果和数据展示等方式,用户可以更好地理解自动驾驶汽车的行驶状况和环境变化。

  总之,使用xviz将自动驾驶汽车的数据转换为可视化的3D场景,可以帮助用户更直观地了解汽车的状态和行驶情况,从而有助于分析和改善自动驾驶汽车的性能和安全性。

以下是一个使用xviz API将xviz数据流渲染成3D场景的示例代码:

// 创建一个XVIZViewer实例,并指定容器节点和视图配置
const viewer = new XVIZViewer(document.getElementById('xviz-container'), {
  showTooltip: true,
  timeline: {
    playbackSpeed: 1.0,
    timestamp: null
  }
});

// 数据流的URL或WebSocket地址
const streamUrl = 'ws://localhost:8081';

// 创建一个XVIZLiveLoader实例用于加载xviz数据流
const loader = new XVIZWebsocketLoader({ sockets: { default: streamUrl } });

// 加载xviz数据流,并在每个新的帧/时间戳上更新场景
loader.onXVIZData = function(frame) {
  viewer.update(frame);
}

// 开始加载xviz数据流
loader.connect();