发布时间:2024-09-23 18:01
本制作采用了:上位机----tx2(ubuntu16.04)
下位机----Arduino 2560
传感器-----思岚rplidar A2
代码见:https://github.com/crjxixixi/cleaner_robot1.git
现在主要对自己的上位机代码进行一些解释:
建立地图的方式有两种:gmapping算法与 hector算法
区别:Gmapping 算法在建立地图时需要机器人雷达的扫描信息与里程计信息
Hector 算法只需要机器人的雷达扫描信息
本实验采取的是hector进行建图:
(1)准备工作:安装hector_slam库
sudo apt-get install ros-kinetic-hector-slam
(2) 创建 hector.launch(本代码在/src/mrobot_navigation/launch)
<launch>
<node pkg=\"hector_mapping\" type=\"hector_mapping\" name=\"hector_mapping\" output=\"screen\">
<!-- Frame names -->
<param name=\"pub_map_odom_transform\" value=\"true\"/>
<param name=\"map_frame\" value=\"map\" />
<param name=\"base_frame\" value=\"base_link\" />
<param name=\"odom_frame\" value=\"base_link\" />
<!-- Tf use -->
<param name=\"use_tf_scan_transformation\" value=\"true\"/>
<param name=\"use_tf_pose_start_estimate\" value=\"false\"/>
<!-- Map size / start point -->
<param name=\"map_resolution\" value=\"0.05\"/>
<param name=\"map_size\" value=\"512\"/>
<param name=\"map_start_x\" value=\"0.5\"/>
<param name=\"map_start_y\" value=\"0.5\" />
<param name=\"laser_z_min_value\" value = \"-1.0\" />
<param name=\"laser_z_max_value\" value = \"1.0\" />
<param name=\"map_multi_res_levels\" value=\"2\" />
<param name=\"map_pub_period\" value=\"2\" />
<param name=\"laser_min_dist\" value=\"0.4\" />
<param name=\"laser_max_dist\" value=\"5.5\" />
<param name=\"output_timing\" value=\"false\" />
<param name=\"pub_map_scanmatch_transform\" value=\"true\" />
<!--<param name=\"tf_map_scanmatch_transform_frame_name\" value=\"scanmatcher_frame\" />-->
<!-- Map update parameters -->
<param name=\"update_factor_free\" value=\"0.4\"/>
<param name=\"update_factor_occupied\" value=\"0.7\" />
<param name=\"map_update_distance_thresh\" value=\"0.2\"/>
<param name=\"map_update_angle_thresh\" value=\"0.06\" />
<!-- Advertising config -->
<param name=\"advertise_map_service\" value=\"true\"/>
<param name=\"scan_subscriber_queue_size\" value=\"5\"/>
<param name=\"scan_topic\" value=\"scan\"/>
</node>
<node pkg=\"tf\" type=\"static_transform_publisher\" name=\"base_to_laser_broadcaster\" args=\"0 0 0 0 0 0 /base_link /laser 100\"/>
<node pkg=\"rviz\" type=\"rviz\" name=\"rviz\"
args=\"-d $(find hector_slam_launch)/rviz_cfg/mapping_demo.rviz\"/>
</launch>
若遇到有不能启动则根据提示安装相应的包就可运行,随着机器人的移动可以在rviz可视化界面中看到你的栅格地图构建的情况。
(3)地图保存
在地图保存之前,需要安装map_server包,在终端中输入:
sudo apt-get install ros-kinetic-map-server
然后,保存图形:
rosrun map_server map_saver -f ~/my_map
~处可以修改为你要存放的地址,本操作将地址保存在根目录下。
由于每个人的机器人外形都不相同,大家可以自己去编写适合自己机器人的urdf,大家可以参考 urdf古月居
在本实验中,由于下位机是采取的Arduino,则在开发时可以将Arduino定义为一个结点来收发话题,从而方便开发(若使用的是stm32进行开发的则需要自己编写串口通信)
1.准备工作
(1)若想要学习如何将Arduino定义为一个结点的大家可以到创客智造中找到相应的教程:
https://www.ncnynl.com/archives/201701/1215.html
(2)Arduino IDE的安装
可以参考教程:https://jingyan.baidu.com/article/219f4bf7e45df3de442d388e.html
(3)ROS相应的导航包安装
2.编写相应的launch文件(可见代码/src/mrobot_navigation/mrobot_nav.launch)
<launch>
<param name=\"use_sim_time\" value=\"false\" />
<arg name=\"use_map_topic\" default=\"false\"/>
<arg name=\"scan_topic\" default=\"scan\"/>
<!-- 配置雷达 -->
<node name=\"rplidarNode\" pkg=\"rplidar_ros\" type=\"rplidarNode\" output=\"screen\">
<param name=\"serial_port\" type=\"string\" value=\"/dev/ttyUSB0\"/>
<param name=\"serial_baudrate\" type=\"int\" value=\"115200\"/>
<param name=\"frame_id\" type=\"string\" value=\"laser\"/>
<param name=\"inverted\" type=\"bool\" value=\"false\"/>
<param name=\"angle_compensate\" type=\"bool\" value=\"true\"/>
</node>
<!--地图信息-->
<arg name=\"map_file\" default=\"/home/xt/my_map.yaml\"/>
<node name=\"map_server\" pkg=\"map_server\" type=\"map_server\" args=\"$(arg map_file)\" />
<!--机器人 move_base -->
<node pkg=\"move_base\" type=\"move_base\" respawn=\"false\" name=\"move_base\" output=\"screen\" clear_params=\"false\">
<rosparam file=\"$(find mrobot_navigation)/config/mrobot1/costmap_common_params.yaml\" command=\"load\" ns=\"global_costmap\" />
<rosparam file=\"$(find mrobot_navigation)/config/mrobot1/costmap_common_params.yaml\" command=\"load\" ns=\"local_costmap\" />
<rosparam file=\"$(find mrobot_navigation)/config/mrobot1/local_costmap_params.yaml\" command=\"load\" />
<rosparam file=\"$(find mrobot_navigation)/config/mrobot1/global_costmap_params.yaml\" command=\"load\" />
<rosparam file=\"$(find mrobot_navigation)/config/mrobot1/base_local_planner_params.yaml\" command=\"load\" />
</node>
<include file=\"$(find mrobot_navigation)/launch/amcl.launch\" />
<!-- 设置坐标-->
<node pkg=\"tf\" type=\"static_transform_publisher\" name=\"base_link_to_laser\" args=\"0.0 0.0 0.0 0.0 0.0 0.0 /base_link /laser 40\" />
<!-- 运行rviz -->
<node pkg=\"rviz\" type=\"rviz\" name=\"rviz\" args=\"-d $(find mrobot_navigation)/rviz/nav.rviz\"/>
</launch>
根据自己的传感器进行相应的配置,本实验中用的是思岚的rplidar A2雷达,所以该launch文件首先对雷达进行了配置
< laser >
<node name=\"rplidarNode\" pkg=\"rplidar_ros\" type=\"rplidarNode\" output=\"screen\">
<param name=\"serial_port\" type=\"string\" value=\"/dev/ttyUSB0\"/>
<param name=\"serial_baudrate\" type=\"int\" value=\"115200\"/>
<param name=\"frame_id\" type=\"string\" value=\"laser\"/>
<param name=\"inverted\" type=\"bool\" value=\"false\"/>
<param name=\"angle_compensate\" type=\"bool\" value=\"true\"/>
设置雷达的串口号、波特率等一些参数,在使用雷达的时候需要给串口权限(根据自己的串口号),本实验中用的是ttyUSB0则给权限如下:
sudo chmod 777 /dev/ttyUSB0
接着加载你刚建好的地图信息:
< map >
<arg name=\"map_file\" default=\"/home/xt/my_map.yaml\"/>
<node name=\"map_server\" pkg=\"map_server\" type=\"map_server\" args=\"$(arg map_file)\" />
将default后面的参数为你地图所在的路径
< move_base > 主要配置机器人的移动时的一些参数(如速度、避障、地图膨胀、路径规划算法)等
<node pkg=\"move_base\" type=\"move_base\" respawn=\"false\" name=\"move_base\" output=\"screen\" clear_params=\"false\">
<rosparam file=\"$(find mrobot_navigation)/config/mrobot1/costmap_common_params.yaml\" command=\"load\" ns=\"global_costmap\" />
<rosparam file=\"$(find mrobot_navigation)/config/mrobot1/costmap_common_params.yaml\" command=\"load\" ns=\"local_costmap\" />
<rosparam file=\"$(find mrobot_navigation)/config/mrobot1/local_costmap_params.yaml\" command=\"load\" />
<rosparam file=\"$(find mrobot_navigation)/config/mrobot1/global_costmap_params.yaml\" command=\"load\" />
<rosparam file=\"$(find mrobot_navigation)/config/mrobot1/base_local_planner_params.yaml\" command=\"load\" />
</node>
</node>
其中base_local_planner_params.yaml、costmap_common_params.yaml、global_costmap_params.yaml、local_costmap_params.yaml文件各参数的配置及其各参数的含义可以看此教程https://www.guyuehome.com/28164
< amcl >
<node pkg=\"amcl\" type=\"amcl\" name=\"amcl\" clear_params=\"true\">
<param name=\"use_map_topic\" value=\"$(arg use_map_topic)\"/>
<!-- translation std dev, m -->
<param name=\"global_frame_id\" value=\"/map\" />
<param name=\"initial_pose_x\" value=\"0.0\"/>
<param name=\"initial_pose_y\" value=\"0.0\"/>
<param name=\"initial_pose_a\" value=\"0.0\"/>
<param name=\"initial_cov_xx\" value=\"0.5*0.5\"/>
<param name=\"initial_cov_yy\" value=\"0.5*0.5\"/>
<param name=\"initial_cov_aa\" value=\"(π/12)*(π/12)\"/>
<param name=\"odom_alpha3\" value=\"0.2\"/>
<param name=\"odom_alpha4\" value=\"0.2\"/>
<param name=\"laser_z_hit\" value=\"0.5\"/>
<param name=\"laser_z_short\" value=\"0.05\"/>
<param name=\"laser_z_max\" value=\"0.05\"/>
<param name=\"laser_z_rand\" value=\"0.5\"/>
<param name=\"laser_sigma_hit\" value=\"0.2\"/>
<param name=\"laser_lambda_short\" value=\"0.1\"/>
<param name=\"laser_model_type\" value=\"likelihood_field\"/>
<param name=\"initial_pose_x\" value=\"0.0\"/>
<param name=\"odom_model_type\" value=\"diff\"/>
<param name=\"odom_alpha5\" value=\"0.1\"/>
<param name=\"gui_publish_rate\" value=\"10.0\"/>
<param name=\"laser_max_beams\" value=\"60\"/>
<param name=\"laser_max_range\" value=\"12.0\"/>
<param name=\"min_particles\" value=\"500\"/>
<param name=\"max_particles\" value=\"2000\"/>
<param name=\"kld_err\" value=\"0.05\"/>
<param name=\"kld_z\" value=\"0.99\"/>
<param name=\"odom_alpha1\" value=\"0.2\"/>
<param name=\"odom_alpha2\" value=\"0.2\"/>
<!-- <param name=\"laser_model_type\" value=\"beam\"/> -->
<param name=\"laser_likelihood_max_dist\" value=\"2.0\"/>
<param name=\"update_min_d\" value=\"0.25\"/>
<param name=\"update_min_a\" value=\"0.2\"/>
<param name=\"odom_frame_id\" value=\"odom\"/>
<param name=\"base_frame_id\" value=\"base_link\"/>
<param name=\"resample_interval\" value=\"1\"/>
<!-- Increase tolerance because the computer can get quite busy -->
<param name=\"transform_tolerance\" value=\"1.0\"/>
<param name=\"recovery_alpha_slow\" value=\"1.0\"/>
<param name=\"recovery_alpha_fast\" value=\"0.0\"/>
<remap from=\"scan\" to=\"$(arg scan_topic)\"/>
</node>
此结点是用于发布机器人的定位信息的功能,详细情况可以参考:http://wiki.ros.org/amcl,大致来说,amcl需要订阅机器人的消息有 1.传感器的信息 2.tf变换 3.地图信息 4.机器人的初始位置,从而通过这些信息来发布 1.机器人的位姿 2.粒子云 3./tf变换(/map–>/odom),这样机器人就能实时的掌握自己所处的位置,并通过mover_base来进行导航。
< rviz >
<node pkg=\"rviz\" type=\"rviz\" name=\"rviz\" args=\"-d $(find mrobot_navigation)/rviz/nav.rviz\"/>
打开rviz可视化工具可以看到机器人在地图上的位置,与导航算法所规划出来的路径。
2.导航操作
导航前需要使用2D Post estimate对机器人位姿进行初始化,使得机器人雷达扫描点与之前所建地图尽可能重合。初始点的好坏对机器人导航效果有着一定的影响。
使用2D NAV Goal点击地图即可为机器人设置导航目标点,机器人会自动规划出行进路线,机器人会循着路径到达设置的地点。