CARLA中有一系列封装好的自动驾驶导航函数库,全部在server的PythonAPI/carla/agents/navigation包中。使用时,可将agents包复制在python文件的同一目录内,方便导入。

navigation包中的文件分为两类: planning and control 和 agent behaviors。从字面意义上看,第一类是路线规划和控制,第二类是自动驾驶agent行为偏好设置。

文档解释:

Planning and control

  • controller.py: Combines longitudinal and lateral PID controllers into a single class, VehiclePIDController, used for low-level control of vehicles from the client side of CARLA.
  • global_route_planner.py: Gets detailed topology from the CARLA server to build a graph representation of the world map, providing waypoint and road option information for the Local Planner.
  • local_planner.py: Follows waypoints based on control inputs from the VehiclePIDController. Waypoints can either be provided by the Global Route Planner or be calculated dynamically, choosing random paths at junctions, similar to the Traffic Manager.

Agent behaviors

  • basic_agent.py: Contains an agent base class that implements a Basic Agent that roams around the map or reaches a target destination in the shortest distance possible, avoiding other vehicles, responding to traffic lights but ignoring stop signs.
  • behavior_agent.py: Contains a class that implements a more complex Behavior Agent that can reach a target destination in the shortest distance possible, following traffic lights, signs, and speed limits while tailgating other vehicles. There are three predefined types that condition how the agent behaves.
  • behavior_types.py: Contains the parameters for the behavior types that condition the Behavior Agent; Cautious, Normal, and Aggressive.

CARLA中使用的车辆控制器是PID Controller,由比例单元(P),积分单元(I)和微分单元(D)组成。透过Kp,Ki和Kd三个参数的设定来实现控制。应用在汽车控制中,分为横向参数(lateral arguments)和纵向参数(longitudinal arguments)。纵向参数负责控制汽车的油门量/刹车量来调整汽车行进的速度,横向参数负责控制汽车的方向盘角度,使得汽车可以一直朝着路径规划好的方向行驶。具体的数学原理和函数定义可以查看controller.py文件中的VehiclePIDController()类。(也可以看我另外两篇文章中关于PID的原理介绍和代码实现,分为速度跟踪和航向控制)

除此之外,CARLA中的路线规划也有集成好的函数库,即global_route_planner.py,其中的GlobalRoutePlanner()类可以直接调取当前地图的地理位置信息,将需要规划的路径的起点和终点坐标两个参数输入,即可输出一条规划好的行车路径,以距起点由近及远的一连串坐标点来表示。

有了合理的行车路径之后,对执行自动驾驶的agent行为偏好还可以有进一步设置,比如“谨慎”,“正常”,“激进”的不同类型,可以模拟不同种类驾驶员习惯的最大行驶速度、巡航速度、刹车反应等驾车行为偏好。

当前为了测验导航系统,先将驾驶环境设置地较为简单,大街上除了测试车辆,无行人,无其他车辆。我分别用“自动控制”和“手动控制”两种方式对导航系统进行了测试。自动控制就是直接调用basic_agent包,由PID Controller对汽车进行控制。手动控制是只从后台调取地图信息生成路径,再根据下一个路径点的位置和距离,手动设置汽车的油门\刹车\转向等参数(简易版的PID Controller)。

无论哪种控制方式,对carla环境的搭建都是一样的,需要生成一个地图,在地图中实例化一辆小车,并设置一个目的地(target_transform)。

import abc
import glob
import os
import sys
from types import LambdaType
from collections import deque
from collections import namedtupletry:sys.path.append(glob.glob('.../WindowsNoEditor/PythonAPI/carla/dist/carla-*%d.%d-%s.egg' % (sys.version_info.major,sys.version_info.minor,'win-amd64' if os.name == 'nt' else 'linux-x86_64'))[0])
except IndexError:passimport carla
import random
import time
import numpy as npclient = carla.Client('localhost',2000)
client.set_timeout(10.0)
world = client.get_world()
blueprint_library = world.get_blueprint_library()
model_3 = blueprint_library.filter('model3')[0]actor_list = []
transform = world.get_map().get_spawn_points()[100] #spwan_points共265个点,选第一个点作为初始化小车的位置
#random.choice(self.world.get_map().get_spawn_points())
vehicle = world.spawn_actor(model_3 , transform)actor_list.append(vehicle)   target_transform = world.get_map().get_spawn_points()[110]

如图所示,小车的初始位置在蓝圈,目的地的位置是红叉,两者的直线距离是292m左右,可以按照绿色虚线的导航行驶。

一、自动控制

我选择了basic_agent测试(和其他偏好的agent原理都是一样的),需要导入BasicAgent类,将汽车作为参数,实例化一个agent。

from agents.navigation.basic_agent import BasicAgent
agent = BasicAgent(vehicle)

之后需要设置导航终点的坐标,须以[x,y,z]的列表形式输入函数。

destination = [target_transform.location.x,target_transform.location.y,target_transform.location.z]
agent.set_destination(destination)

设置好后即可开始模拟,通过while循环可以使小车慢慢靠近目的地,直到到达结束循环。(规划的路径不止一条,汽车可能会在十字路口处随机选择可行的路径)

while True:if agent.done():print("The target has been reached, stopping the simulation")breakcontrol=agent.run_step()vehicle.apply_control(control)for agent in actor_list:    agent.destroy()
print('done')

这种方式非常简单便捷,使用现有的集成函数,可以保持汽车一直行驶在车道的正中间,不随意变道;前方遇到红绿灯也会自动识别,不违反交规;如果检测到周围有其他车,还会主动避让。但正是因为这种方式直接从地图底层信息读取的数据太多,甚至达到了“万物互联”的高度,与真实环境的条件相差甚远,很难进一步向现实应用推广了(目前的真实地理因素不可能从环境底层代码获取到红绿灯和周围汽车的信息)。因此我考虑了另一种手动控制的方式,即只能从地图信息中读取到规划的路径点(现有的手机地图导航技术即可完成),其他的环境因素还是需要通过传感器来获取,再根据传感器获取的数据来确定驾驶的参数。

二、手动控制

在简单的测试环境下(暂时不考虑移动障碍物或信号灯),可以将汽车的巡航速度设置成一个恒定值。寻路的重点在于,如何根据汽车自身的坐标和方向,及目标点的坐标,计算出转向的角度。对于路线在海拔上的高度变化,汽车无法通过方向盘控制,所以目前只考虑平面上的移动(xOy坐标系)。

(carla地图是左手系不是右手系让我也很疑惑)

由图中所示,汽车的朝向

从汽车到目标地点的方向向量

两向量之间的夹角θ可以用夹角公式来计算

但是这样计算的θ是没有正负的,θ的取值范围是[0,pi],这时候可以通过判断两向量的叉乘的符号来确定向量夹角的正负。

当叉乘结果大于0时,θ大于0,表示目标地点在汽车当前方向的右侧,反之,表示目标地点在汽车当前方向的左侧。θ的取值范围变成了[-pi,pi]。

但控制方向的参数steer的范围是[-1,1](代表方向盘从最左转到最右),如果将θ值直接用作方向盘的旋转量,当目标地点的角度超过1弧度(57°),方向盘就会打死。除此之外,在方向角有细微变动的时候,汽车的方向盘也会跟随变化,容易导致汽车左右来回摇摆。因此,考虑采用量化的方式,完成方向角到方向盘旋转量的转化。

(阈值我根据目前的测试结果设置的一个较为效果较好的值,可以根据之后测试效果再调整)

用代码实现时,需要导入两个类,其中GlobalRoutePlannerDAO类是数据访问层,用于从GlobalRoutePlanner实例中获取数据

from agents.navigation.global_route_planner import GlobalRoutePlanner
from agents.navigation.global_route_planner_dao import GlobalRoutePlannerDAO

对二者进行实例化,需要将当前地图作为参数输入,再对路径规划的实例进行初始化。

env_map = world.get_map()
dao = GlobalRoutePlannerDAO(env_map,3)#3表示每隔3m采样一个路径点,路径点越密集,路径的精度越高
grp = GlobalRoutePlanner(dao)
grp.setup()

将方向角转化用代码表示:

def get_angle(angle):if angle>1.39:#79.64°return 1elif angle<-1.39:return -1elif angle>1:#57.3°return 0.5elif angle<-1:return -0.5elif angle>0.2:#11.46°return 0.3elif angle<-0.2:return -0.3else:return 0

开始进行模拟,由于路径规划出的最后路径点,与目的地的坐标可能会有一些差异,接近目的地时,可能会重新规划路线。所以设置当路径规划的路径点少于3个时,不再考虑路径点,而直接朝向终点的坐标开。每次汽车做出一个action等待0.2秒,当距离目的地的坐标小于5米时,可以认为已经到达终点,汽车停止驾驶,结束循环。

while True:route_way_point =grp.trace_route(vehicle.get_transform().location,target_transform.location)if len(route_way_point)>3:temp_target = route_way_point[1][0]#target_mat=temp_target.transform.get_matrix()else:temp_target = target_transformtarget_mat=temp_target.get_matrix()target_dis = target_transform.location.distance(vehicle.get_location())car_mat=vehicle.get_transform().get_matrix()    car_dir=np.array([car_mat[0][0],car_mat[1][0]])s_dir = np.array([target_mat[0][3]-car_mat[0][3],target_mat[1][3]-car_mat[1][3]])cos_theta=np.dot(car_dir,s_dir)/(np.linalg.norm(car_dir)*np.linalg.norm(s_dir))left_right = abs(np.cross(car_dir,s_dir))/np.cross(car_dir,s_dir)angle = np.arccos(cos_theta)*left_rightvehicle.apply_control(carla.VehicleControl(throttle=0.4, steer=get_angle(angle), brake=0.0, hand_brake=False, reverse=False))time.sleep(0.2)v = vehicle.get_velocity()kmh = int(3.6 * np.sqrt(v.x**2 + v.y**2 + v.z**2))print('v:',kmh,'kmh\t','left_distance:',int(target_dis),'m')if target_dis<5:vehicle.apply_control(carla.VehicleControl(throttle=0.0, steer=0, brake=1, hand_brake=False, reverse=False))print('arrive target location!')breakfor agent in actor_list:agent.destroy()
print('done')

使用CARLA模拟器实现DQN自动驾驶(三)导航系统相关推荐

  1. 使用CARLA模拟器实现DQN自动驾驶(一)安装环境

    CARLA是一个自动驾驶环境仿真软件(官网),自带python API,对于Q-learning或DQN来说,能从环境中及时获得反馈非常重要.因此自带API的模拟器对于python编程实现自动驾驶非常 ...

  2. 使用CARLA模拟器实现DQN自动驾驶(二)搭建神经网络

    由于图像数据的结构复杂,数据量大,考虑到用没有超强算力的电脑运行程序的时候,为了简化模型结构,对数据进行压缩,摄像头传来的图像先设置为80*60. 为了让模型能学到正确的参数,需要对智能体的actio ...

  3. Carla 使用神经网络训练自动驾驶车辆---数据采集部分

    Carla 使用神经网络训练自动驾驶车辆-数据采集 本文是基于carla训练一个神经网络模型,用于预测车辆的方向盘转角,因此需要在carla中构建环境进行数据采集: 首先构造一个carla类,用于初始 ...

  4. carla与ros2的自动驾驶算法-planning与control算法开发与仿真

    欢迎仪式 carla与ros2的自动驾驶算法-planning与control算法开发与仿真 欢迎大家来到自动驾驶Player(L5Player)的自动驾驶算法与仿真空间,在这个空间我们将一起完成这些 ...

  5. 使用 Carla 和 Python 的自动驾驶汽车第 4 部分 —— 强化学习代理

    在我们的自动驾驶汽车的第四部分,Carla, Python, TensorFlow,和强化学习项目,我们将为我们的实际代理编码.在前一篇教程中,我们研究了环境类,我们的代理将与之交互. 在考虑如何创建 ...

  6. 使用 Carla 和 Python 的自动驾驶汽车第 4 部分 —— 强化学习Action

    欢迎来到自动驾驶汽车的第五部分,并与Carla.Python和TensorFlow加强学习. 现在我们已经有了环境和代理,我们只需要添加更多的逻辑将它们连接在一起,这是我们接下来要做的. 首先,我们将 ...

  7. 使用 Carla 和 Python 的自动驾驶汽车第 2 部分 —— 控制汽车并获取传感器数据

    欢迎来到 Carla 自动驾驶汽车教程系列的第 2 部分.在本教程中,我们将向您介绍 Carla 的 Python API 方面. 首先,Carla 中有几种类型的对象: world:这是你的环境: ...

  8. Carla自动驾驶模拟器使用教程Python编程 #最全最源

    本文来自转载,学习了很多篇Carla相关的博客,都是源自这两个系列教程,所以看着一篇足够了(入门) 一.Carla入门 Carla的基本架构与介绍 Carla安装 基础Python API的使用 Ca ...

  9. 【转载】模拟器,会是自动驾驶的下一个刺激战场吗?

    模拟器,会是自动驾驶的下一个刺激战场吗? 雷锋网 百家号08-2111:36 在亚利桑那州梅萨的南隆摩街和西南大街的拐角处有一个左转黄灯,自动驾驶行业内的人士习惯戏称它为"死亡之地" ...

最新文章

  1. 实战排查由于系统负载引起的服务响应异常
  2. Windows7_x64下编译64位ffmpeg
  3. Sklearn(v3)——SVM理论(1)
  4. mysql union join_MySQL 超新手入门(5) JOIN 与 UNION 查询
  5. dd命令测试linux磁盘io情况,【LINUX】正确的使用dd进行磁盘读写速度测试
  6. LiveVideoStackCon 2022 上海站 专题抢先看
  7. ezdpl Linux自动化部署实战
  8. nssl1257-A【数论】
  9. jdk7与jdk8环境共存与切换
  10. animate动画案例_animate动画案例——小小购物狂
  11. 企业实战_07_MyCat 搭建Mysql 一主一从复制环境
  12. 微信小程序一键获取用户头像、昵称等基本信息
  13. 卡方拟合优度检验(非参)
  14. verilog实现状态机
  15. Android软件开发用什么语言?
  16. React-Navigation(二),goBack的使用(两级)
  17. 牛客网第九场多校联赛 E Music Game
  18. 《超智游戏》:鬼影投手·棒球1号位
  19. 未成年帐号登录华为游戏,启动后不断弹出防沉迷提示
  20. C语言 CJSON使用实例

热门文章

  1. ​​​windows上传ipa到开发者中心(app store)的方法​​
  2. X264代码走读二(intra_refresh实现)
  3. 聊聊无线充电——华为Mate RS保时捷版无线充电器详解(上篇)
  4. FANSEA泛海微MCU单片机IC方案LED智能紫外(UVC+UVA)消毒灯
  5. Python基础之集合
  6. 从王者荣耀看设计模式(十.外观模式)
  7. phpcms实现PC网站接入微信Native支付
  8. ROS(ERROR):Rosdep cannot find all required resources to answer your query
  9. java学习笔记——springmvc 之 数据自定义转换器 数据格式化 JSR303数据校验返回与接收JSON(@RequestBody 和 @ResponseBody)
  10. day11-函数作业