在之前的博客已经实现了并行实时运算以及风险场的计算,验证了理论的可行性,接下来就是与已有设备相结合,搭建完整项目。在本文中将实现将罗技G923与旭日X3派联动。

项目组成:

 1. 旭日X3派接收将车辆感知数据进行图形化输出传递给驾驶人,在实际仿真操作中,需要当车辆传感器传回相关感知信息后,算法对感知信息进行处理,将前方车路风险进行量化,并将量化的结果进行图形化输出至显示设备中。2. 将前方车路风险进行量化,构建形成风险场。将旭日X3派作为L3自动驾驶的风险计算中间件,负责风险计算以及控制权调整。 3. 主机在仿真软件构建小车,罗技G923与旭日X3派连接,主机构建自动驾驶算法,将控制结果传输至旭日X3派,人机控制加权。 4.将加权后的结果传输给仿真软件中的小车。

具体思路如下:

  1. 车辆感知数据处理:

    • 使用旭日X3派接收车辆感知数据,并将其传递给算法处理模块。
    • 在算法处理模块中,对接收到的感知信息进行处理,包括障碍物检测、距离计算等。
    • 根据处理结果,进行前方车路风险的量化,构建风险场。
  2. 风险计算与控制权调整:

    • 将旭日X3派作为风险计算中间件,负责风险计算和控制权调整。
    • 根据风险场的计算结果,进行风险评估,并确定需要采取的控制动作。
    • 将控制结果传输给主机,用于自动驾驶算法的执行。
  3. 自动驾驶算法与人机控制加权:

    • 在主机上构建自动驾驶算法,包括路径规划、速度控制等模块。
    • 将风险计算中的控制结果与自动驾驶算法的输出进行加权处理,以实现人机控制加权。
    • 将加权后的结果传输给仿真软件中的小车,控制小车的行驶。

捕获罗技G923数据,并进行UDP转发。

以下是详细过程:

基于旭日X3派的人机共驾控制器行车风险场计算这一篇文章,已经验证了将旭日X3派作为L3自动驾驶的风险计算中间件,负责风险计算以及控制权调整。为了使驾驶人更好了解到行车过程中的风险因素,获得当前道路的风险情况,所以首先要将前方车路风险进行量化,并将量化的结果进行图形化输出至显示设备中。

首先在仿真软件中设置场景:

在L3智能驾驶算法中,将记录传感器数据:

EGO_CONTROL_FORMAT = 'time@i,valid@b,throttle@d,brake@d,steer@d,mode@i,gear@i'

EGO_STATE_FORMAT = 'time@i,x@d,y@d,z@d,yaw@d,pitch@d,roll@d,speed@d'

EGO_EXTRA_FORMAT = 'time@i,VX@d,VY@d,VZ@d,AVx@d,AVy@d,AVz@d,Ax@d,Ay@d,Az@d,AAx@d,AAy@d,AAz@d'

Object_Perception_FORMAT_0 = 'Timestamp@i,64@[,OBJ_ID@i,OBJ_Class@b,OBJ_X@d,OBJ_Y@d,OBJ_Z@d,OBJ_Velocity@d,' \
                             'OBJ_Length@d,OBJ_Width@d,OBJ_Height@d'
LANE_FORMAT_0 = "Timestamp@i,4@[,Lane_ID@i,Lane_Distance@d,Lane_Car_Distance_Left@d,Lane_Car_Distance_Right@d," \
                "Lane_Curvature@d,Lane_Coefficient_C0@d,Lane_Coefficient_C1@d,Lane_Coefficient_C2@d," \
                "Lane_Coefficient_C3@d,Lane_Class@b"

通过《用旭日X3派实现L3自动驾驶场景下并行实时运算》一文中叙述的方法,将这些数据传输到旭日X3派中进行进一步处理。

其次是初始化道路背景图以及车辆初始位置:

import matplotlib.pyplot as plt
import numpy as np
# 道路长宽
road_len = 55
road_wid = 9

# 道路边界
road_left = -5
road_right = road_len - 5
road_bottom = -road_wid / 2
road_top = road_wid / 2

# 车辆信息
car1_pos = np.array([32.591397864490695, 3.9399475062054847])  # 相对坐标
car1_size = np.array([4.9, 2.4])  # 长, 宽
car2_pos = np.array([25.241397959858126, -0.010049442036702771])
car2_size = np.array([5.4, 2.21])
car3_pos = np.array([10.971398455768771, -3.1200500523882653])
car3_size = np.array([5.15, 2.04])
ego_pos = np.array([0, 0])
ego_size = np.array([5.0, 1.82])

def calculate_risk_field(grid_size, range_size, ego_pos, obstacles):
    grid_x, grid_y = np.meshgrid(np.arange(-range_size, range_size + 1, grid_size),
                                 np.arange(-range_size, range_size + 1, grid_size))
    risk_field = np.zeros_like(grid_x)

    for obs in obstacles:
        distance = np.sqrt((grid_x - obs[0]) ** 2 + (grid_y - obs[1]) ** 2)
        angle_diff = np.arctan2(obs[1] - ego_pos[1], obs[0] - ego_pos[0]) - ego_pos[2]
        angle_diff = np.abs((angle_diff + np.pi) % (2 * np.pi) - np.pi)
        risk_field += (1.0 / distance) * angle_diff

    return risk_field


ego_pos = np.array([0, 0, 0])
obstacles = [car1_pos, car2_pos, car3_pos]

grid_size = 1
range_size = 25
risk_field = calculate_risk_field(grid_size, range_size, ego_pos, obstacles)

fig, ax = plt.subplots(figsize=(12, 5))

# 道路
ax.add_patch(plt.Rectangle((road_left, road_bottom), road_right - road_left, road_wid, color='gray'))

# 车道线
for i in range(1, 3):
    ax.plot([road_left, road_right], [road_bottom + i * line_spacing, road_bottom + i * line_spacing], '--',
            color='white', linewidth=1)

# 车辆
for pos, size, color in zip([car1_pos, car2_pos, car3_pos, ego_pos], [car1_size, car2_size, car3_size, ego_size],
                            ['r', 'b', 'g', 'k']):
    circle = plt.Circle(pos, radius=size[1] / 2, color=color)
    ax.add_patch(circle)


# 坐标轴和标签
ax.set_xlim(road_left, road_right)
ax.set_ylim(road_bottom - 1, road_top + 1)
ax.set_aspect('equal')
ax.set_xlabel('X (m)')
ax.set_ylabel('Y (m)')
ax.set_title('Road Map with Risk Field')


plt.show()

在此场景中,主车将经过三辆车辆,这三辆车辆与主车远近不一,但是分别分布在三个车道,如图所示为生成的道路背景图与车辆初始位置:

由于安装的旭日X3派系统为带有图形化操作界面的系统,所以将HDMI线连接至显示器,负责显示可视化输出:

在《基于旭日X3派的人机共驾控制器行车风险场计算》已经可以计算出每一时刻的风险场,接下来就需要在显示屏上循环更新风险场。

# 不断循环更新风险场
while True:
    # 获取行车数据并更新风险场
    data = get_car_data()
    update_risk_map(risk_map, data)
    
    # 将风险场绘制到背景图片中
    risk_img = cv2.cvtColor(risk_map, cv2.COLOR_GRAY2BGR)
    final_img = cv2.addWeighted(bg_img, 0.5, risk_img, 0.5, 0)
    
    # 在屏幕上显示结果
    cv2.imshow('Risk Map', final_img)
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

cv2.destroyAllWindows()

在这个过程中,驾驶人可以实时观察到现在的风险情况,并且通过自己在前挡风玻璃看到的前方道路情况与显示屏显示的行车风险场进行对比,当驾驶人注意到风险场与自己观察结果产生不一致的情况下,可以立刻接管车辆,避免发生危险。如图所示是呈现效果:

在图中,红色为风险最高,蓝色为风险最低,可以有效通过右侧屏幕显示结果与前方视线结果进行对比。

在下一博客中,将介绍具体的L3人机共驾控制器在旭日X3派的实现以及与罗技方向盘的连接。