前提:安装carla,carla-ros-bridge与autoware
可参考我之前写的博文
1.启动carla
在CARLA_0.9.13目录下
./CarlaUE4.sh
2.启动carla ros bridge
在~/carla/ros_ws路径下
source devel/setup.bash
roslaunch carla_ros_bridge carla_ros_bridge_with_example_ego_vehicle.launch
3.启动autoware
在autoware-1.14路径下
source devel/setup.bash
roslaunch runtime_manager runtime_manager.launch
4.启动 carla autoware bridge(话题转发功能包)
参考链接:Carla Ros Autoware 联合仿真——安装、源码修改、数据预处理
需要进行话题转发的原因是:ros bridge的脚本中对各个传感器话题的frame做了设定,而且各个frame之间的tf关系同样固定,可以通过脚本修改,但是这些源码分布在很多地方,修改不易,更好的选择是进行话题转发的同时,修改frame名称和frame的tf关系。
话题转发包括2个部分,一个是传感器数据的话题转发,另一个是autoware规划后的控制指令geometry::TwistStamped,转换为carla的控制指令。
carla ros bridge中提供了carla twist to contral节点,这个节点用于将geometry::Twist 类型的ros消息转化为carla中车辆的控制指令,但是autoware规划器输出的控制命令为geometry::TwistStamped类型,做一个简单的转换即可。下面是carla twist to contral节点的说明。
链接:carla twist to control官方文档
自己新建carla_bridge工作空间,在src目录下新建carla_bridge1.cpp文件
代码如下
#include <ros/ros.h>
#include <iostream>
#include "sensor_msgs/Imu.h"
#include "sensor_msgs/PointCloud2.h"
#include "geometry_msgs/TwistStamped.h"
#include "geometry_msgs/Twist.h"
#include <tf/transform_broadcaster.h>
#include <tf/transform_datatypes.h>
//定义发接收者
ros::Subscriber imu_sub;
ros::Subscriber lidar_sub;
ros::Subscriber twist_sub;
//定义发送者
ros::Publisher imu_adv;
ros::Publisher lidar_adv;
ros::Publisher twist_adv;
//定义话题名称
const std::string IMU_TOPIC = "/carla/ego_vehicle/imu";//这些是carla ros bridge发出的ros topic
const std::string LIDAR_TOPIC = "/carla/ego_vehicle/lidar";
const std::string TWIST_TOPIC = "/twist_cmd";//订阅autoware的控制指令,TwistStamped,把它转成carla ros bridge的控制指令Twist
geometry_msgs::Twist m_twist;
void imu_callback(const sensor_msgs::Imu::Ptr &imu_msg)//imu数据回调
{
imu_msg->header.frame_id = "imu";//更换frame名称
imu_msg->header.stamp = ros::Time::now();
imu_adv.publish(*imu_msg);
}
void lidar_callback(const sensor_msgs::PointCloud2::Ptr& lidar_msg)//lidar数据回调
{
lidar_msg->header.frame_id = "lidar";
lidar_msg->header.stamp = ros::Time::now();
lidar_adv.publish(*lidar_msg);
}
//autoware发出的车辆控制指令,需要转化为ros bridge需要的geometry_msgs::Twist类型
void twist_callback(const geometry_msgs::TwistStamped::Ptr& twist_msg)//TwistStamped数据回调
{
m_twist.linear = twist_msg->twist.linear;
m_twist.angular = twist_msg->twist.angular;
twist_adv.publish(m_twist);
}
int main(int argc,char **argv){
ros::init(argc,argv,"Carla_Bridge");
ros::NodeHandle n;
imu_sub = n.subscribe(IMU_TOPIC,10000,imu_callback);
lidar_sub = n.subscribe(LIDAR_TOPIC,10000,lidar_callback);
twist_sub = n.subscribe(TWIST_TOPIC,10,twist_callback);
imu_adv = n.advertise<sensor_msgs::Imu>("/imu_raw", 10000);
lidar_adv = n.advertise<sensor_msgs::PointCloud2>("/points_raw", 10000);
twist_adv = n.advertise<geometry_msgs::Twist>("/carla/ego_vehicle/twist", 10);//ros bridge carla_twist_to_contral节点
ros::spin();
}
修改carla_bridge CMakeLists.txt
add_executable(carla_bridge src/carla_bridge1.cpp)
target_link_libraries(carla_bridge ${catkin_LIBRARIES})
frame的tf关系在launch文件中修改,这里命名为carla_bridge_sim.launch,内容如下:
<launch>
<node pkg="carla_bridge" type="carla_bridge" name="carla_bridge1"/>
<node pkg="tf" type="static_transform_publisher" name="lidar_baselink" args="0 0 1.0 0 0 0 base_link lidar 10" />
<node pkg="tf" type="static_transform_publisher" name="imu_baselink" args="-0.3 0 0.4 0 0 0 base_link imu 100" />
<node pkg="tf" type="static_transform_publisher" name="world_map" args="0 0 0 0 0 0 world map 10" />
</launch>
在carla_bridge工作空间下
source devel/setup.bash
roslaunch carla_bridge_launch carla_bridge_sim.launch
5.在rs_ws路径下启动carla_twist_to_control转换节点
source devel/setup.bash
roslaunch carla_twist_to_control carla_twist_to_control.launch role_name:="ego_vehicle"
6.启动autoware中相应的节点(建图、规划等等均可)
Setup界面设置如下
Map界面设置如下,导入Town10HD的地图,因为launch文件里面default是默认地图,默认的就是Town10HD,切记TF不要点,因为话题转发的时候,launch文件就已经实现了坐标转换。同时导入Vector Map。
在Sensing页面中,点击Points Preprocessor下ring_ground_filter右侧的app按钮,在弹出的界面中设置点云话题名input_point_topic为/points_raw,Sensor Model选32,设置完参数后点击OK退出,最后勾选ring_ground_filter。
在Computing页面下,点击lidar_localizer下ndt_matching右侧的app按钮,在弹出的页面中topic:/config/ndt选择Initial Pos选项,x,y,z,roll,pitch,yaw的值表示激光数据的初始位姿,如果有GNSS设备可以选择GNSS进行初始定位。Method Type选择pcl_anh_gpu,即使用GPU进行点云匹配计算,然后点击OK,若使用GPU进行点云匹配计算较为卡顿,可勾选Method Type选择pcl_generic,最后勾选ndt_matching,完成ndt定位。注意小车的初始位姿,Location的两个数值分别在x和y值修改,Heading的度数要转换成弧度制。
设置初始位姿
可以看到初始位姿匹配上!
点击autoware_connector下vel_pose_connect右侧的app按钮,在弹出的界面中确定没有勾选Simulation_Mode,退出并勾选vel_pose_connect。
点击OpenPlanner-Global Planning下op_global_planner后面的app按钮,勾选 Replanning、Smooth和Rviz Goals选项, Replanning用于到达目标点后,可以重新规划到下一个目标点,Smooth用于平滑全局路径,Rviz Goals用于在rviz中设置导航目标点,点击OK退出后勾选op_global_planner
在rviz左下角点击Add按钮,弹出的显示框中点击By topic按钮,找到话题/vector_map_center_lines_rviz的MakerArray并添加,则rviz中汽车正前方出现了一条中线。
在rviz中点击2D Nav Goal按钮,在出现的中线远离汽车一端上设置导航目标点(目标点尽量靠近中线),然后就可以看到规划出来的全局路径:
勾选OpenPlanner-Local planning中所有选项
在autoware的Computing页面中,Motion Planning下可以看到waypoint_follower,点击pure_puesuit右侧的app按钮,弹出如下界面,路点跟随的速度选择为Waypoint,点击OK按钮后勾选pure_puesuit。
点击twist_filter右侧的app按钮,弹出如下界面,对速度进行滤波,参数默认即可,点击OK按钮后勾选twist_filter。
此时汽车开始移动,如下所示: