网站搭建后台,wordpress 开启链接,python语言入门,wordpress冷门二次元主题文章目录 一.官方网址1.ROS官网2.urdf-模型3.rviz-数据可视化4.gazebo-仿真环境5.gmapping-建图6.navigation-导航 二.文件框架三.启动顺序0.依赖包的安装1.手动控制的启动顺序2.建图的启动顺序3.导航的启动顺序 四.urdf-模型文件1.ackermann.xacro-轮子传动的配置2.common_pro… 文章目录 一.官方网址1.ROS官网2.urdf-模型3.rviz-数据可视化4.gazebo-仿真环境5.gmapping-建图6.navigation-导航 二.文件框架三.启动顺序0.依赖包的安装1.手动控制的启动顺序2.建图的启动顺序3.导航的启动顺序 四.urdf-模型文件1.ackermann.xacro-轮子传动的配置2.common_properties.xacro-rviz里模型颜色3.xju_tricycle_model.gazebo.xacro-gazebo配置3.xju_tricycle_model.urdf.xacro-模型文件 五.手动控制1.tricycle.launch-启动模型文件节点2.tricycle_control.launch-关节控制节点3.servo_commands.py-速度分配节点4.transform.py-速度转换节点5.gazebo_odometry.py-里程计计算节点6.tele_key.launch-键盘控制节点7.ackermann_teleop.py-手动控制界面节点 六.建图-gmapping1.slam_gmapping.launch-建图节点 七.导航-navigation1.costmap_common_params.yaml-局路径规划与本地路径规划通用参数2.global_costmap_params.yaml-全局规划地图的参数3.local_costmap_params.yaml-局部规划地图的参数4.move_base_params.yaml-底盘控制的参数配置5.teb_local_planner_params.yaml-基本的局部规划器参数配置6.move_base.launch-导航节点 一.官方网址 注这些网址的服务器都是在国外访问比较慢是正常情况。 1.ROS官网
https://www.ros.org/
2.urdf-模型
http://wiki.ros.org/cn/urdf
http://wiki.ros.org/xacro
3.rviz-数据可视化
http://wiki.ros.org/rviz
http://wiki.ros.org/rqt
4.gazebo-仿真环境
http://wiki.ros.org/gazebo 有些情况下gazebo后台关闭不彻底需要用命令行强制关闭 killall gzserver
killall gzclient5.gmapping-建图
http://wiki.ros.org/gmapping
6.navigation-导航
http://wiki.ros.org/navigation
二.文件框架
ys001_ws // 工作空间 work space用来存放项目的相关文件
├── build // 编译空间Build Space用来存储工作空间编译过程中产生的缓存信息和中间文件
├── devel // 开发空间Development Space用来放置编译生成的可执行文件。
└── src // 代码空间Source Space开发过程中最常用的文件夹用来存储所有ROS功能包的源码文件。├── CMakeLists.txt - /opt/ros/noetic/share/catkin/cmake/toplevel.cmake└── model // 包名 Package 功能包(ROS基本单元)包含多个节点、库与配置文件包名所有字母小写只能由字母、数字与下划线组成├── CMakeLists.txt // 包的配置文件 配置编译规则比如源文件、依赖项、目标文件├── package.xml //包的信息 比如:包名、版本、作者、依赖项...(以前版本是 manifest.xml)├── config //模型的配置信息 │ └── my_car.rviz //rviz后缀为 rviz插件保存的配置文件下次打开rviz可以读取这个配置好的文件。├── debug.py // 调式用的脚本其他正常的项目不一定与这个文件自己定义的。├── launch // 启动的脚本文件 可一次性运行多个节点 │ ├── move_base_amcl.launch //定位用的启动文件│ ├── move_base.launch //导航的启动文件│ ├── slam_gmapping.launch //建图的启动文件│ ├── tele_key.launch //键盘控制的启动文件│ ├── tricycle_control.launch//模型控制的启动文件│ └── tricycle.launch //rviz和gazebo的模型启动文件├── map //存放扫好的地图文件│ ├── my_01_map.pgm //图片格式的地图文件 与 同名的 .yaml 配合使用│ ├── my_01_map.yaml //地图的扫描文件 与同名的 .pgm配合使用│ ├── my_02_map.pgm│ └── my_02_map.yaml├── param //控制模型导航算法的参数设置文件│ ├── ackermann_control.yaml // 控制关节的配置信息│ ├── ackermann_teleop_param.yaml // 手动控制的速度和角度配置信息│ ├── costmap_common_params.yaml // 代价地图的公共参数配置│ ├── global_costmap_params.yaml // 全局地图的参数配置│ ├── local_costmap_params.yaml // 局部地图的参数配置│ ├── move_base_params.yaml // 底盘控制的参数配置│ └── teb_local_planner_params.yaml // 路径规划的参数配置├── scripts //存放python的脚本文件│ ├── ackermann_teleop.py //键盘wasd控制的脚本│ ├── servo_commands.py //解析键盘控制的控制信息脚本│ └── transform.py //手动控制是定义cml_vel的节点│ ├── gazebo_odometry.py //gazebo里的里程计计算脚本│ ├── send_goals_A.py //发生目标点的脚本,下同│ ├── send_goals_B.py│ ├── send_goals_C.py│ ├── send_goals_D.py│ ├── send_goals_origin.py│ ├── send_goals_work.py├── src //存放CPP源文件├── urdf //存放描述模型的文件│ ├── ackermann.xacro //阿克曼模型类的轮子传动配置│ ├── common_properties.xacro //rviz里模型的颜色│ ├── xju_tricycle_model.gazebo.xacro //gazebo仿真传感器配置文件│ └── xju_tricycle_model.urdf.xacro // 模型文件└── worlds //存放gazebo的世界模型文件└── simple.world
三.启动顺序
0.依赖包的安装 在正式运行之前务必安装下面这些包手动安装一条一条的安装或者配置sh文件来批量安装可以参考下面的配置来操作; sudo apt-get install ros-noetic-ackermann-msgs
sudo apt-get install ros-noetic-navigation
sudo apt-get install ros-noetic-openslam-gmapping
sudo apt-get install ros-noetic-geographic-info
sudo apt-get install ros-noetic-controller-manager
sudo apt-get install ros-noetic-gazebo-ros-control
sudo apt-get install ros-noetic-effort-controllers
sudo apt-get install ros-noetic-joint-state-controller
sudo apt-get install ros-noetic-position-controllers
sudo apt-get install ros-noetic-teb-local-planner
sudo apt-get install ros-noetic-gmapping配置批量安装 用记事本新建一文件保存时后缀名为“.sh”,这里为“install.sh”其内容如下 在.sh文件所在目录打开终端输入sh install.sh #!/bin/sh
sudo apt-get -y install ros-noetic-ackermann-msgs
sudo apt-get -y install ros-noetic-navigation
sudo apt-get -y install ros-noetic-openslam-gmapping
sudo apt-get -y install ros-noetic-geographic-info
sudo apt-get -y install ros-noetic-controller-manager
sudo apt-get -y install ros-noetic-gazebo-ros-control
sudo apt-get -y install ros-noetic-effort-controllers
sudo apt-get -y install ros-noetic-joint-state-controller
sudo apt-get -y install ros-noetic-position-controllers
sudo apt-get -y install ros-noetic-teb-local-planner
sudo apt-get -y install ros-noetic-gmapping1.手动控制的启动顺序
步骤1启动模型在gazebo和rviz的显示
roslaunch model tricycle.launch步骤2启动键盘控制的节点
roslaunch model tele_key.launch2.建图的启动顺序
步骤1启动模型在gazebo和rviz的显示
roslaunch model tricycle.launch步骤2启动建图的节点
roslaunch model slam_gmapping.launch步骤3启动保存地图的节点 注意后面的路径要改成自己的路径这里的地图名为“my_0_map”保存之后会在目标的目录下生成两个文件 .pgm .yaml 文件 rosrun map_server map_saver -f /home/z/ros_ws/ys001_ws/src/model/map/my_01_map3.导航的启动顺序
步骤1启动模型在gazebo和rviz的显示
roslaunch model tricycle.launch步骤2启动导航的节点
roslaunch model move_base.launch四.urdf-模型文件
1.ackermann.xacro-轮子传动的配置 给仿真环境配置哪些轮子需要控制为后面控制的仿真做好硬件关节的仿真。 参考 https://blog.csdn.net/qq_23670601/article/details/88741802 ?xml version1.0 ?
!-- 轮子传动的宏函数 --
robot namexju xmlns:xacrohttp://ros.org/wiki/xacro!-- 转向关节的配置 --xacro:macro namewheel_transmission paramsnametransmission name${name}_transmission typeSimpleTransmissiontypetransmission_interface/SimpleTransmission/typejoint name${name}_jointhardwareInterfacehardware_interface/EffortJointInterface/hardwareInterface/jointactuator name${name}_motorhardwareInterfacehardware_interface/EffortJointInterface/hardwareInterfacemechanicalReduction1/mechanicalReduction/actuator/transmission/xacro:macro!-- 驱动关节的配置 --xacro:macro namesteering_hinge_transmission paramsnametransmission name${name}_transmission typeSimpleTransmissiontypetransmission_interface/SimpleTransmission/typejoint name${name}_jointhardwareInterfacehardware_interface/EffortJointInterface/hardwareInterface/jointactuator name${name}_motorhardwareInterfacehardware_interface/EffortJointInterface/hardwareInterfacemechanicalReduction1/mechanicalReduction/actuator/transmission/xacro:macro/robot具体解释 必须唯一指定了一个传动的标签名字自己定义方便起见可以使用与joint name相同的名字。 出现一次定义了传动的类型这个细节说明还没找到用transmission_interface/SimpleTransmission就可以啦。 可定义一个或多个指定这个传动所依赖的关节拥有如下标签hardwareInterface。 在joint下可定义一个或多个指定支持的硬件接口空间。用于结合控制器使用硬件接口来向硬件接口发送和接受指令请注意 当在RobotHW中加载此transmission时此标签的值应为hardware_interface / XXX。 在Gazebo中加载此transmission时此标记的值应为XXX 。 定义一个或多个传动连接的致动器名字自己去定义拥有如下标签mechanicalReduction及hardwareInterface。 可选定义电机关节减速比。 可选,只有Indigo及以前版本的在这里指定目前版本已经移到joint标签下指定支持的硬件接口空间 2.common_properties.xacro-rviz里模型颜色 这里的颜色设定是给rviz里显示用的gazebo里的颜色和rviz的颜色是分开的两者不是同一个软件插件。 rgba 表示 红色 绿色 蓝色 透明度颜色占比用0.0-1.0表示透明度也是如此。 ?xml version1.0 ?
!-- rviz模型里颜色属性的初始化 rgba 表示 红色 绿色 蓝色 透明度颜色占比用0.0-1.0表示透明度也是如此。
--
robot namexacro_properties xmlns:xacrohttp://ros.org/wiki/xacro!-- Init colour -- material nameblackcolor rgba0.0 0.0 0.0 1.0//materialmaterial namedarkcolor rgba0.3 0.3 0.3 1.0//materialmaterial namelight_blackcolor rgba0.4 0.4 0.4 1.0//materialmaterial namebluecolor rgba0.0 0.0 0.8 1.0//materialmaterial namegreencolor rgba0.0 0.8 0.0 1.0//materialmaterial namegreycolor rgba0.5 0.5 0.5 1.0//materialmaterial nameorangecolor rgba${255/255} ${108/255} ${10/255} 1.0//materialmaterial namebrowncolor rgba${222/255} ${207/255} ${195/255} 1.0//materialmaterial nameredcolor rgba0.8 0.0 0.0 1.0//materialmaterial namewhitecolor rgba1.0 1.0 1.0 1.0//material
/robot
3.xju_tricycle_model.gazebo.xacro-gazebo配置 1.设置模型在gazebo里面的颜色参考https://blog.csdn.net/qq_42226250/article/details/110881207 2.设置轮子的摩擦力和刚度系数参考https://blog.csdn.net/qq_27865227/article/details/125001773 3.设置gazebo里的传感器插件plugin参考http://admin.guyuehome.com/36462 注意实际中传感器数据来源于传感器厂商提供的驱动和配到的发布节点。 ?xml version1.0?
!-- gazebo的配置文件1.设置gazebo里模型的颜色2.设置传感器参数--
robot namexju xmlns:xacrohttp://ros.org/wiki/xacro
!-- 雷达激光和IMU可见性的设置 --xacro:arg namelaser_visual defaulttrue/xacro:arg nameimu_visual defaultfalse/!-- 设置连杆的在gazebo里的颜色 --gazebo referencebase_linkmaterialGazebo/Orange/material/gazebogazebo referencewash_linkmaterialGazebo/Blue/material/gazebogazebo referencepic_linkmaterialGazebo/face/material/gazebogazebo referencefront_steering_hingematerialGazebo/Black/material/gazebogazebo referencefront_wheelmaterialGazebo/Black/material/gazebo!-- 后轮的物理特性设置 mu1,mu2代表摩擦力kp,kd代表刚性系数 --gazebo referenceleft_rear_wheelmu1 value2.0/mu2 value2.0/kp value10000000.0 /kd value1.0 /fdir1 value1 0 0/materialGazebo/Black/material/gazebogazebo referenceright_rear_wheelmu1 value2.0/mu2 value2.0/kp value10000000.0 /kd value1.0 /fdir1 value1 0 0/materialGazebo/Black/material/gazebo!-- IMU传感器 --gazebo referenceimu_linksensor typeimu nameimualways_ontrue/always_onvisualize$(arg imu_visual)/visualize/sensormaterialGazebo/FlatBlack/material/gazebogazeboplugin nameimu_plugin filenamelibgazebo_ros_imu.soalwaysOntrue/alwaysOnbodyNameimu_link/bodyNameframeNameimu_link/frameNametopicNameimu/topicNameserviceNameimu_service/serviceNamegaussianNoise0.0/gaussianNoiseupdateRate50/updateRateimunoisetypegaussian/typeratemean0.0/meanstddev2e-4/stddevbias_mean0.0000075/bias_meanbias_stddev0.0000008/bias_stddev/rateaccelmean0.0/meanstddev1.7e-2/stddevbias_mean0.01/bias_meanbias_stddev0.001/bias_stddev/accel/noise/imu/plugin/gazebo!-- 雷达传感器 --gazebo referencelaser_linkmaterialGazebo/Red/materialsensor typeray namelds_lfcd_sensorpose0 0 0 0 0 0/posevisualize$(arg laser_visual)/visualizeupdate_rate10/update_raterayscanhorizontalsamples1800/samplesresolution1/resolutionmin_angle-1.57079637/min_anglemax_angle3.1415926/max_angle/horizontal/scanrangemin0.001/minmax20/maxresolution0.01/resolution/rangenoisetypegaussian/typemean0.0/meanstddev0.01/stddev/noise/rayplugin namegazebo_ros_lds_lfcd_controller filenamelibgazebo_ros_laser.sotopicNamescan/topicNameframeNamelaser_link/frameName/plugin/sensor/gazebo!-- 控制插件 用于仿真控制驱动和转向的接口 --gazeboplugin namegazebo_ros_control filenamelibgazebo_ros_control.sorobotNamespace/xju/robotNamespacerobotParamrobot_description/robotParamrobotSimTypegazebo_ros_control/DefaultRobotHWSim/robotSimTypelegacyModeNStrue/legacyModeNS/plugin/gazebo/robot
3.xju_tricycle_model.urdf.xacro-模型文件 1.建立三维模型 2.建立各个部件的坐标关系即tf关系 参考https://blog.csdn.net/Kalenee/article/details/86485565 ?xml version1.0?
!-- 1.建立模型2.建立tf关系
--
robotnamexju xmlns:xacrohttp://ros.org/wiki/xacro!-- 引入其他文件 --xacro:include filename$(find model)/urdf/ackermann.xacro/xacro:include filename$(find model)/urdf/xju_tricycle_model.gazebo.xacro/xacro:include filename$(find model)/urdf/common_properties.xacro/!-- 变量 base 底盘 m质量 l 长度 w 宽度 h高度 --xacro:property namebase_m value10 / xacro:property namebase_l value1.2 /xacro:property namebase_w value1 /xacro:property namebase_h value0.8 /!-- wheel 轮子 r半径 l长度 --xacro:property namewheel_r value0.1 /xacro:property namewheel_l value0.08 /!-- real 后轮 x方向的坐标 r_y 右轮y坐标 l_y 左轮的y坐标--xacro:property namereal_x value-0.4 /xacro:property namereal_r_y value-0.5 /xacro:property namereal_l_y value0.5 /!-- 轮子的z坐标 --xacro:property namewheel_z value${-(base_h/2)} /!-- 驱动轮和转向关节的 effort 力矩 velocity 速度--xacro:property nameeffort value30 /xacro:property namevelocity value50 /!-- 宏定义 --xacro:macro nameBox_inertial_matrix paramsm l w hinertialmass value${m} /inertia ixx${m*(h*h l*l)/12} ixy 0 ixz 0iyy${m*(w*w l*l)/12} iyz 0izz${m*(w*w h*h)/12} //inertial/xacro:macro!-- Body 底盘 --link namebase_footprint/joint namebase_footprint_to_base_link typefixedparent linkbase_footprint/child linkbase_link/origin xyz0 0 ${(base_h/2)wheel_r} //jointlink namebase_linkvisualoriginxyz0 0 0rpy0 0 0 /geometrybox size${base_l} ${base_w} ${base_h} //geometrymaterial nameorange //visualcollisionoriginxyz0 0 0rpy0 0 0 /geometrybox size${base_l} ${base_w} ${base_h} //geometry/collisionxacro:Box_inertial_matrix m${base_m} l${base_l} w${base_w} h${base_h} //link!-- 清洗滚筒 --link namewash_linkinertialorigin xyz0 0 0 rpy0 0 0 /mass value0.5 /inertia ixx1.35E-05 ixy0 ixz0 iyy2.5E-05 iyz0 izz1.35E-05 //inertialvisualorigin xyz0 0 0 rpy0 0 0 /geometrycylinder length3 radius0.5 //geometrymaterial namegreen //visualcollisionorigin xyz0 0 0 rpy1.57 0 0 /geometrycylinder length0.01 radius0.005 //geometry/collision/linkjoint namewash_joint typefixedorigin xyz0 -0.5 ${wheel_z1.5} rpy0 0 0 /parent linkbase_link /child linkwash_link /axis xyz0 0 1 //joint!-- 轮子
--!-- 前轮转向关节 --link namefront_steering_hingeinertialorigin xyz0 0 0 rpy0 0 0 /mass value0.5 /inertia ixx1.35E-05 ixy0 ixz0 iyy2.5E-05 iyz0 izz1.35E-05 //inertialvisualorigin xyz0 0 0 rpy1.57 0 0 /geometrycylinder length0.0001 radius0.00001 //geometrymaterial nameblack //visualcollisionorigin xyz0 0 0 rpy1.57 0 0 /geometrycylinder length0.01 radius0.005 //geometry/collision/linkjoint namefront_steering_hinge_joint typerevoluteorigin xyz0.6 0 ${wheel_z} rpy0 0 0 /parent linkbase_link /child linkfront_steering_hinge /axis xyz0 0 1 /!-- 转向关节的限位 lower upper revolute类型 joint的单位为弧度--!-- effort 最大力矩 N*m velocity rad/s 最大速度 http://wiki.ros.org/pr2_controller_manager/safety_limits --limit lower-0.87266 upper0.87266 effort${effort} velocity${velocity}//jointxacro:steering_hinge_transmission namefront_steering_hinge /!-- 前轮 --link namefront_wheelinertialorigin xyz0 0 0 rpy0 0 0 /mass value2 /inertia ixx0.002867 ixy0 ixz0 iyy0.0049 iyz0 izz0.002867 //inertialvisualorigin xyz0 0 0 rpy1.57 0 0 /geometrycylinder length${wheel_l} radius${wheel_r} //geometrymaterial nameblack //visualcollisionorigin xyz0 0 0 rpy1.57 0 0 /geometrycylinder length${wheel_l} radius${wheel_r} //geometry/collision/linkjoint namefront_wheel_joint typecontinuousorigin xyz0 0 0 rpy0 0 0 /parent linkfront_steering_hinge /child linkfront_wheel /axis xyz0 1 0 /limit effort${effort} velocity${velocity} //jointxacro:wheel_transmission namefront_wheel /!-- 左后轮 --link nameleft_rear_wheelinertialorigin xyz0 0 0 rpy0 0 0 /mass value2 /inertia ixx0.002867 ixy0 ixz0 iyy0.0049 iyz0 izz0.002867 //inertialvisualorigin xyz0 0 0 rpy1.57 0 0 /geometrycylinder length${wheel_l} radius${wheel_r} //geometrymaterial nameblack //visualcollisionorigin xyz0 0 0 rpy1.57 0 0 /geometrycylinder length${wheel_l} radius${wheel_r} //geometry/collision/linkjoint nameleft_rear_wheel_joint typecontinuousorigin xyz${real_x} ${real_l_y} ${wheel_z} rpy0 0 0 /parent linkbase_link /child linkleft_rear_wheel /axis xyz0 1 0 /limit effort0 velocity1000 //jointxacro:wheel_transmission nameleft_rear_wheel /!-- 右后轮 --link nameright_rear_wheelinertialorigin xyz0 0 0 rpy0 0 0 /mass value2 /inertia ixx0.002867 ixy0 ixz0 iyy0.0049 iyz0 izz0.002867 //inertialvisualorigin xyz0 0 0 rpy1.57 0 0 /geometrycylinder length${wheel_l} radius${wheel_r} //geometrymaterial nameblack //visualcollisionorigin xyz0 0 0 rpy1.57 0 0 /geometrycylinder length${wheel_l} radius${wheel_r} //geometry/collision/linkjoint nameright_rear_wheel_joint typecontinuousorigin xyz${real_x} ${real_r_y} ${wheel_z} rpy0 0 0 /parent linkbase_link /child linkright_rear_wheel /axis xyz0 1 0 /limit effort0 velocity1000 //jointxacro:wheel_transmission nameright_rear_wheel /!-- Lidar --link namelaser_linkvisualoriginxyz0 0 0rpy0 0 0 /geometrycylinder length0.04 radius0.03 //geometrymaterial namered //visual/linkjointnamejoint_top_ladartypefixedoriginxyz0.57 0.4 0.42rpy0 0 0 /parentlinkbase_link /childlinklaser_link /axisxyz0 0 0 /safety_controllerk_velocity0 //joint!-- Imu --link nameimu_link/jointnamejoint_imutypefixedoriginxyz0 0 0rpy0 0 0 /parentlinkbase_link /childlinkimu_link /axisxyz0 0 0 /safety_controllerk_velocity0 //joint/robot
五.手动控制
1.tricycle.launch-启动模型文件节点 加载模型在gazeb和rviz显示 launch
!-- 在gazebo里的初始位置 --arg namex_pos default-7.0/arg namey_pos default-7.0/arg namez_pos default1/arg namegui defaulttrue/!-- 导入 模型和世界--!-- 模型文件 --param namerobot_description command$(find xacro)/xacro $(find model)/urdf/xju_tricycle_model.urdf.xacro/include file$(find gazebo_ros)/launch/empty_world.launch!-- 世界模型-可改为自己的 --arg nameworld_name value$(find model)/worlds/simple.world/arg namepaused valuefalse/arg nameuse_sim_time valuetrue/arg namegui value$(arg gui)/arg nameheadless valuefalse/arg namedebug valuefalse//include!-- 加载控制器 --node pkggazebo_ros typespawn_model namespawn_urdfargs-urdf -model xju -x $(arg x_pos) -y $(arg y_pos) -z $(arg z_pos) -param robot_description /!-- 加载关节控制的节点 --include file$(find model)/launch/tricycle_control.launch /!-- 键盘控制 需要一起启动时 可以把注释打开--!-- rosparam commandload file$(find model)/param/ackermann_teleop_param.yaml /node pkgmodel typeackermann_teleop.py nameackermann_teleop / --!-- 启动 rviz --node pkgrviz typerviz namerviz args-d $(find model)/config/my_car.rviz//launch
2.tricycle_control.launch-关节控制节点
?xml version1.0?launch!-- 导入控制参数 --rosparam file$(find model)/param/ackermann_control.yaml commandload/!-- 控制管理器 并载入需要控制的关节 --node namecontroller_manager pkgcontroller_manager typespawner respawnfalseoutputscreen ns/xju argsfront_wheel_velocity_controllerfront_steering_hinge_position_controllerjoint_state_controller/!-- 读取节点状态 并且发布到tf里 --node name robot_state_publisher pkg robot_state_publisher type robot_state_publisherremap from/joint_states to/xju/joint_states//node!-- 速度分配节点 --node pkgmodel typeservo_commands.py nameservo_commands outputscreen/!-- 速度转换节点 --node pkgmodel typetransform.py nametransform outputscreen/!-- 里程计节点 --node pkgmodel namegazebo_odometry_node typegazebo_odometry.py/
/launch
3.servo_commands.py-速度分配节点
#!/usr/bin/env python3
将速度分配给每一个驱动电机import rospy
from std_msgs.msg import Bool
from std_msgs.msg import Float32
from std_msgs.msg import Float64
from ackermann_msgs.msg import AckermannDriveStampedflag_move 0def set_throttle_steer(data):global flag_movepub_vel_front_wheel rospy.Publisher(/xju/front_wheel_velocity_controller/command, Float64, queue_size1)pub_pos_front_steering_hinge rospy.Publisher(/xju/front_steering_hinge_position_controller/command, Float64, queue_size1)throttle data.drive.speed*14.5steer data.drive.steering_anglepub_vel_front_wheel.publish(throttle)pub_pos_front_steering_hinge.publish(steer)def servo_commands():rospy.init_node(servo_commands, anonymousTrue)rospy.Subscriber(/ackermann_cmd_mux/output, AckermannDriveStamped, set_throttle_steer, queue_size1, buff_size52428800, tcp_nodelayTrue)# spin() simply keeps python from exiting until this node is stoppedrospy.spin()if __name__ __main__:try:servo_commands()except rospy.ROSInterruptException:pass4.transform.py-速度转换节点
#!/usr/bin/env python3
将 cmd_vel 的速度信息转换为 小车需要的速度信息
import rospy
import std_msgs.msg
from ackermann_msgs.msg import AckermannDriveStamped
from geometry_msgs.msg import Twistimport time
import threading
pub rospy.Publisher(/ackermann_cmd_mux/output, AckermannDriveStamped,queue_size1)def thread_job():rospy.spin()def callback(data):speed data.linear.xturn data.angular.zmsg AckermannDriveStamped();msg.header.stamp rospy.Time.now();msg.header.frame_id base_link;msg.drive.speed speed;msg.drive.acceleration 1;msg.drive.jerk 1;msg.drive.steering_angle turnmsg.drive.steering_angle_velocity 1pub.publish(msg)def SubscribeAndPublish():rospy.init_node(nav_sim, anonymousTrue)rospy.Subscriber(cmd_vel, Twist, callback,queue_size1,buff_size52428800)#rospy.Subscriber(cmd_vel, Twist, callback,queue_size1,buff_size52428800)rospy.spin()if __name__ __main__:try:SubscribeAndPublish()except rospy.ROSInterruptException:pass
5.gazebo_odometry.py-里程计计算节点 实际中这个里程计改为实物的编码器传回来的数据 #!/usr/bin/env python3
This script makes Gazebo less fail by translating gazebo status messages to odometry data.
Since Gazebo also publishes data faster than normal odom data, this script caps the update to 20hz.
Winter Guerra
从gazebo 仿真环境里获得里程计信息.
import rospy
from nav_msgs.msg import Odometry
from geometry_msgs.msg import Pose, Twist, Transform, TransformStamped
from gazebo_msgs.msg import LinkStates
from std_msgs.msg import Header
from ackermann_msgs.msg import AckermannDriveStamped
import numpy as np
import math
import tf
import tf2_rosclass OdometryNode:# Set publisherspub_odom rospy.Publisher(/odom, Odometry, queue_size1)def __init__(self):# init internalsself.last_received_pose Pose()self.last_received_twist Twist()self.vel_direction 1.self.last_recieved_stamp None# Set the update raterospy.Timer(rospy.Duration(.02), self.timer_callback) # 50hzself.tf_pub tf2_ros.TransformBroadcaster()# Set subscribers 从link状态里获取rospy.Subscriber(/gazebo/link_states, LinkStates, self.sub_robot_pose_update, queue_size1, buff_size52428800, tcp_nodelayTrue)rospy.Subscriber(/ackermann_cmd_mux/output, AckermannDriveStamped, self.get_vel_direction, queue_size1, buff_size52428800, tcp_nodelayTrue)def sub_robot_pose_update(self, msg):# Find the index of the robottry:arrayIndex msg.name.index(xju::base_footprint)except ValueError as e:# Wait for Gazebo to startuppasselse:# Extract our current position informationtime_diff 0.02if self.last_recieved_stamp is not None:time_diff (rospy.Time.now() - self.last_recieved_stamp).to_sec()if time_diff 0.:returnself.last_received_twist.linear.x self.vel_direction * math.sqrt((msg.pose[arrayIndex].position.x - self.last_received_pose.position.x)**2 (msg.pose[arrayIndex].position.y - self.last_received_pose.position.y)**2) / time_diff(r1, p1, y1) tf.transformations.euler_from_quaternion([msg.pose[arrayIndex].orientation.x, msg.pose[arrayIndex].orientation.y, msg.pose[arrayIndex].orientation.z, msg.pose[arrayIndex].orientation.w])(r2, p2, y2) tf.transformations.euler_from_quaternion([self.last_received_pose.orientation.x, self.last_received_pose.orientation.y, self.last_received_pose.orientation.z, self.last_received_pose.orientation.w])self.last_received_twist.angular.z (y1 - y2) / time_diffself.last_received_pose msg.pose[arrayIndex]self.last_recieved_stamp rospy.Time.now()def get_vel_direction(self, msg):if msg.drive.speed 0:self.vel_direction -1.else:self.vel_direction 1.def timer_callback(self, event):if self.last_recieved_stamp is None:returncmd Odometry()cmd.header.stamp self.last_recieved_stampcmd.header.frame_id odomcmd.child_frame_id base_footprintcmd.pose.pose self.last_received_posecmd.twist.twist self.last_received_twistcmd.pose.covariance [1e-3, 0, 0, 0, 0, 0,0, 1e-3, 0, 0, 0, 0,0, 0, 1e6, 0, 0, 0,0, 0, 0, 1e6, 0, 0,0, 0, 0, 0, 1e6, 0,0, 0, 0, 0, 0, 1e3]cmd.twist.covariance [1e-9, 0, 0, 0, 0, 0,0, 1e-3, 1e-9, 0, 0, 0,0, 0, 1e6, 0, 0, 0,0, 0, 0, 1e6, 0, 0,0, 0, 0, 0, 1e6, 0,0, 0, 0, 0, 0, 1e-9]self.pub_odom.publish(cmd)tf TransformStamped(headerHeader(frame_idcmd.header.frame_id,stampcmd.header.stamp),child_frame_idcmd.child_frame_id,transformTransform(translationcmd.pose.pose.position,rotationcmd.pose.pose.orientation))self.tf_pub.sendTransform(tf)# Start the node
if __name__ __main__:rospy.init_node(gazebo_odometry_node)node OdometryNode()rospy.spin()6.tele_key.launch-键盘控制节点
launch
!-- 键盘控制 --!-- 加载参数 --rosparam commandload file$(find model)/param/ackermann_teleop_param.yaml /!-- 启动键盘控制节点 --node pkgmodel typeackermann_teleop.py nameackermann_teleop /
/launch
7.ackermann_teleop.py-手动控制界面节点
#!/usr/bin/env python3# Copyright (c) 2019, The Personal Robotics Lab, The MuSHR Team, The Contributors of MuSHR
# License: BSD 3-Clause. See LICENSE.md file in root directory.# 导入第三方库
import atexit
import os
import signal
from threading import Lock
from tkinter import Frame, Label, Tkimport rospy
from ackermann_msgs.msg import AckermannDriveStamped# 定义需要控制的键
UP w
LEFT a
DOWN s
RIGHT d
QUIT qstate [False, False, False, False]
state_lock Lock()
state_pub None
root None
control Falsedef keyeq(e, c):return e.char c or e.keysym cdef keyup(e):global stateglobal controlwith state_lock:if keyeq(e, UP):state[0] Falseelif keyeq(e, LEFT):state[1] Falseelif keyeq(e, DOWN):state[2] Falseelif keyeq(e, RIGHT):state[3] Falsecontrol Truedef keydown(e):global stateglobal controlwith state_lock:if keyeq(e, QUIT):shutdown()elif keyeq(e, UP):state[0] Truestate[2] Falseelif keyeq(e, LEFT):state[1] Truestate[3] Falseelif keyeq(e, DOWN):state[2] Truestate[0] Falseelif keyeq(e, RIGHT):state[3] Truestate[1] Falsecontrol sum(state) 0# Up - linear.x 1.0
# Down - linear.x -1.0
# Left - angular.z 1.0
# Right - angular.z -1.0def publish_cb(_):global controlwith state_lock:if not control:returnack AckermannDriveStamped()if state[0]:ack.drive.speed max_velocityelif state[2]:ack.drive.speed -max_velocityif state[1]:ack.drive.steering_angle max_steering_angleelif state[3]:ack.drive.steering_angle -max_steering_angleif state_pub is not None:state_pub.publish(ack)control sum(state) 0def exit_func():os.system(xset r on)def shutdown():root.destroy()rospy.signal_shutdown(shutdown)def main():global state_pubglobal rootglobal max_velocityglobal max_steering_anglemax_velocity rospy.get_param(~speed,2.0)max_steering_angle rospy.get_param(~max_steering_angle, 0.6)state_pub rospy.Publisher(/ackermann_cmd_mux/output, AckermannDriveStamped, queue_size1)rospy.Timer(rospy.Duration(0.1), publish_cb)atexit.register(exit_func)os.system(xset r off)root Tk()root.attributes(-topmost,1) # 窗口置顶frame Frame(root, width100, height100)frame.bind(KeyPress, keydown) # 监听事件frame.bind(KeyRelease, keyup)frame.pack()frame.focus_set()lab Label(frame,height10,width30,text聚焦窗口 wads控制 Q 退出,)lab.pack()print(Press %c to quit % QUIT)root.mainloop()if __name__ __main__:rospy.init_node(keyboard_teleop, disable_signalsTrue)signal.signal(signal.SIGINT, lambda s, f: shutdown())main()六.建图-gmapping 在手动控制的基础上添加建图节点 参考 https://www.bilibili.com/video/BV1mJ411R7Ni?p37vd_source45f9a599303782222954b67591ac1ed9 http://wiki.ros.org/gmapping https://blog.csdn.net/m0_63647490/article/details/123130882 https://blog.csdn.net/qq_42037180/article/details/100819788 1.slam_gmapping.launch-建图节点
launch!-- 输入的参数 与自己配置的发布话题一致 --arg namescan_topic defaultscan / arg namebase_frame defaultbase_footprint/arg nameodom_frame defaultodom/param nameuse_sim_time valuefalse/!-- 下面的很多参数默认即可 --!--不备注的默认参数--node pkggmapping typeslam_gmapping nameslam_gmapping outputscreenparam namebase_frame value$(arg base_frame)/ !--底盘坐标系--param nameodom_frame value$(arg odom_frame)/ !--里程计坐标系-- !--remap fromscan tobase_scan/--param namemap_update_interval value1.0/ !--更新时间(s)每多久更新一次地图不是频率--param namemaxUrange value20/ !--激光雷达最大可用距离在此之外的数据截断不用--param namesigma value0.05/ param namekernelSize value1/param namelstep value0.05/param nameastep value0.05/param nameiterations value5/param namelsigma value0.075/param nameogain value3.0/param namelskip value0/param namesrr value0.01/param namesrt value0.02/param namestr value0.01/param namestt value0.02/param namelinearUpdate value0.5/ !--每次机器人移动这么远时处理一次扫描 越高越准越耗资源--param nameangularUpdate value0.218/ !--每次机器人旋转这么远时处理一次扫描--param nametemporalUpdate value5.0/param nameresampleThreshold value0.5/param nameparticles value80/ !-- 很重要算法中的粒子数选择适合的才能又准又快 --param namexmin value-1.0/param nameymin value-1.0/param namexmax value1.0/param nameymax value1.0/param namedelta value0.05/param namellsamplerange value0.01/param namellsamplestep value0.01/param namelasamplerange value0.005/param namelasamplestep value0.005//node
/launch七.导航-navigation 在手动控制的基础上扫好图的基础上添加导航节点 参考 http://wiki.ros.org/navigation#Basic_ROS_Navigation_Tutorials http://www.autolabor.com.cn/book/ROSTutorials/di-7-zhang-ji-qi-ren-dao-822a28-fang-771f29/72-dao-hang-shi-xian/724-dao-hang-shi-xian-04-lu-jing-gui-hua.html https://blog.csdn.net/majingming123/article/details/128236979 下面的五个 “.yaml”文件是导航参数的配置关键需要先准备好 可能会出现机器人在本地路径规划时与全局路径规划不符而进入膨胀区域出现假死的情况如何尽量避免这种情形呢 全局路径规划与本地路径规划虽然设置的参数是一样的但是二者路径规划和避障的职能不同可以采用不同的参数设置策略: 全局代价地图可以将膨胀半径和障碍物系数设置的偏大一些本地代价地图可以将膨胀半径和障碍物系数设置的偏小一些。 这样在全局路径规划时规划的路径会尽量远离障碍物而本地路径规划时机器人即便偏离全局路径也会和障碍物之间保留更大的自由空间从而避免了陷入“假死”的情形。 1.costmap_common_params.yaml-局路径规划与本地路径规划通用参数 包括:机器人的尺寸、距离障碍物的安全距离、传感器信息等。配置参考如下: obstacle_range: 2.5 # 用于障碍物探测比如: 值为 3.0意味着检测到距离小于 3 米的障碍物时就会引入代价地图才会被识别到
raytrace_range: 3.0 #用于清除障碍物比如值为 3.5意味着清除代价地图中 3.5 米以外的障碍物只有在这个范围内不存在的才会被消除#机器人几何参如果机器人是圆形设置 robot_radius,如果是其他形状设置 footprint
# footprint: [[-0.08, -0.15], [-0.08, 0.15],[0.42, 0.15], [0.42, -0.15]]
robot_radius: 0.2#膨胀半径扩展在碰撞区域以外的代价区域使得机器人规划路径避开障碍物
inflation_radius: 0.2 #膨胀半径transform_tolerance: 0.5#导航包所需要的传感器
observation_sources: scan#对传感器的坐标系和数据进行配置
scan: data_type: LaserScan topic: scan marking: true clearing: true# 地图类型
map_type: costmap2.global_costmap_params.yaml-全局规划地图的参数
global_costmap:global_frame: map #地图坐标系robot_base_frame: base_footprint #机器人坐标系# 以此实现坐标变换update_frequency: 1.0 #代价地图更新频率publish_frequency: 0.5 #代价地图的发布频率static_map: true # 是否使用一个地图或者地图服务器来初始化全局代价地图transform_tolerance: 0.5 #等待坐标变换发布信息的超时时间cost_scaling_factor: 10.0inflation_radius: 0.25
3.local_costmap_params.yaml-局部规划地图的参数
local_costmap:global_frame: map #里程计坐标系robot_base_frame: base_footprint #机器人坐标系update_frequency: 5.0 #代价地图更新频率publish_frequency: 2.0 #代价地图的发布频率static_map: false #不需要静态地图可以提升导航效果rolling_window: true #是否使用动态窗口默认为false在静态的全局地图中地图不会变化width: 5 # 局部地图宽度 单位是 mheight: 5 # 局部地图高度 单位是 mresolution: 0.05 # 局部地图分辨率 单位是 m一般与静态地图分辨率保持一致transform_tolerance: 0.5cost_scaling_factor: 5inflation_radius: 0.254.move_base_params.yaml-底盘控制的参数配置 shutdown_costmaps: false #当move_base在不活动状态时,是否关掉costmapcontroller_frequency: 5.0 #向底盘控制移动话题cmd_vel发送命令的频率.
controller_patience: 3.0 #在空间清理操作执行前,控制器花多长时间等有效控制下发planner_frequency: 0.5 #全局规划操作的执行频率.如果设置为0.0,则全局规划器仅#在接收到新的目标点或者局部规划器报告路径堵塞时才会重新执行规划操作
planner_patience: 5.0 #在空间清理操作执行前,留给规划器多长时间来找出一条有效规划.oscillation_timeout: 10.0 #执行修复机制前,允许振荡的时长.
oscillation_distance: 0.1 #来回运动在多大距离以上不会被认为是振荡conservative_reset_dist: 0.1
5.teb_local_planner_params.yaml-基本的局部规划器参数配置 这个配置文件设定了机器人的最大和最小速度限制值也设定了加速度的阈值。 局部路径规划有多种的规划方案如DWA、TEB、PMC等阿克曼使用的是TEB即有最小转向半径限制。 参考http://www.xbhp.cn/news/158710.html 动态调参rosrun rqt_reconfigure rqt_reconfigure TebLocalPlannerROS:# 使用teb的局部规划器odom_topic: odommap_frame: /odom# Trajectoty 这部分主要是用于调整轨迹teb_autosize: True #优化期间允许改变轨迹的时域长度dt_ref: 0.3 #期望的轨迹时间分辨率dt_hysteresis: 0.03 #根据当前时间分辨率自动调整大小的滞后现象通常约为。建议使用dt ref的10%#覆盖全局规划器提供的局部子目标的方向;规划局部路径时会覆盖掉全局路径点的方位角,#对于车辆的2D规划,可以设置为False,可实现对全局路径的更好跟踪。global_plan_overwrite_orientation: True#指定考虑优化的全局计划子集的最大长度,如果为0或负数禁用长度也受本地Costmap大小的限制max_global_plan_lookahead_dist: 3.0 feasibility_check_no_poses: 1 #检测位姿可到达的时间间隔default4#如果为true则在目标落后于起点的情况下可以使用向后运动来初始化基础轨迹#(仅在机器人配备了后部传感器的情况下才建议这样做allow_init_with_backwards_motion: Falseglobal_plan_viapoint_sep: -1#参数在TebLocalPlannerROS::pruneGlobalPlan()函数中被使用#该参数决定了从机器人当前位置的后面一定距离开始裁剪#就是把机器人走过的全局路线给裁剪掉因为已经过去了没有比较再参与计算后面的局部规划global_plan_prune_distance: 1exact_arc_length: Falsepublish_feedback: False# Robotmax_vel_x: 3 # X 方向最大速度max_vel_x_backwards: 1max_vel_theta: 2 # 最大角度acc_lim_x: 3 # X 加速限制acc_lim_theta: 2 # 角速度加速限制#仅适用于全向轮# max_vel_y (double, default: 0.0) # acc_lim_y (double, default: 0.5)# ********************** Carlike robot parameters ********************min_turning_radius: 0.26 # 最小转弯半径 注意车辆运动学中心是后轮中点wheelbase: 0.258 # 即前后轮距离#设置为true时ROS话题rostopic cmd_vel/angular/z 内的数据是舵机角度cmd_angle_instead_rotvel: True # ********************************************************************footprint_model: # types: point, circular, two_circles, line, polygon 多边形勿重复第一个顶点会自动闭合type: line# radius: 0.2 # for type circularline_start: [-0.13, 0.0] # for type lineline_end: [0.13, 0.0] # for type line# front_offset: 0.2 # for type two_circles# front_radius: 0.2 # for type two_circles# rear_offset: 0.2 # for type two_circles# rear_radius: 0.2 # for type two_circles# vertices: [ [0.25, -0.05], [0.18, -0.05], [0.18, -0.18], [-0.19, -0.18], [-0.25, 0], [-0.19, 0.18], [0.18, 0.18], [0.18, 0.05], [0.25, 0.05] ] # for type polygon# GoalTolerance 目标公差xy_goal_tolerance: 0.2yaw_goal_tolerance: 0.1#自由目标速度。设为False时车辆到达终点时的目标速度为0。#TEB是时间最优规划器。缺少目标速度约束将导致车辆“全速冲线”free_goal_vel: False# complete_global_plan: True # Obstaclesmin_obstacle_dist: 0.3 # 与障碍的最小期望距离,include_costmap_obstacles: True #应否考虑到局部costmap的障碍设置为True后才能规避实时探测到的、建图时不存在的障碍物。costmap_obstacles_behind_robot_dist: 2.0 #考虑后面n米内的障碍物obstacle_poses_affected: 30 #为了保持距离每个障碍物位置都与轨道上最近的位置相连。costmap_converter_spin_thread: Truecostmap_converter_rate: 5# Optimization 优化参数no_inner_iterations: 5 # 被外循环调用后内循环执行次数no_outer_iterations: 4 # 执行外循环优化次数optimization_activate: True # 激活优化过程optimization_verbose: False # 打印优化过程penalty_epsilon: 0.1 # 对硬约束近似weight_max_vel_x: 2 # 最大速度权重weight_max_vel_theta: 1 # 最大角速度权重weight_acc_lim_x: 1 # 最大加速度权重weight_acc_lim_theta: 1 # 最大角速度权重weight_kinematics_nh: 1000 weight_kinematics_forward_drive: 1 #抑制倒车的权重正常设置1weight_kinematics_turning_radius: 1 #最小转弯半径我们没必要最小转弯weight_optimaltime: 1 #优化时间参数让小车多走直线和内道weight_obstacle: 50 # 优化过程中和障碍物最小距离权重weight_dynamic_obstacle: 10 # not in use yet # 动态障碍物最小距离权重alternative_time_cost: False # not in use yet selection_alternative_time_cost: False# Homotopy Class Plannerenable_homotopy_class_planning: Falseenable_multithreading: Falsesimple_exploration: Falsemax_number_classes: 4roadmap_graph_no_samples: 15roadmap_graph_area_width: 5h_signature_prescaler: 0.5h_signature_threshold: 0.1obstacle_keypoint_offset: 0.1obstacle_heading_threshold: 0.45visualize_hc_graph: False# # Recovery# shrink_horizon_backup: True# shrink_horizon_min_duration: 10# oscillation_recovery: True# oscillation_v_eps: 0.1# oscillation_omega_eps: 0.1# oscillation_recovery_min_duration: 10# oscillation_filter_duration: 106.move_base.launch-导航节点
launch!-- move_base节点 及加载的参数配置 --node pkgmove_base typemove_base respawnfalse namemove_base outputscreen!-- 全局路径规划与本地路径规划时调用的通用参数 --rosparam file$(find model)/param/costmap_common_params.yaml commandload nsglobal_costmap / rosparam file$(find model)/param/costmap_common_params.yaml commandload nslocal_costmap /rosparam file$(find model)/param/local_costmap_params.yaml commandload /rosparam file$(find model)/param/global_costmap_params.yaml commandload / rosparam file$(find model)/param/teb_local_planner_params.yaml commandload /rosparam file$(find model)/param/move_base_params.yaml commandload /param namebase_local_planner valueteb_local_planner/TebLocalPlannerROS /!--param namecontroller_frequency value10 /param namecontroller_patiente value15.0/--/node!-- 这里改成自己的地图名称 --node namemap_server pkgmap_server typemap_server args$(find model)/map/my_02_map.yaml outputscreenparam nameframe_id valuemap//node!-- 速度转换节点 --node namenav_sim pkgmodel typetransform.py /node!-- amcl节点 定位用的配置参数 --arg nameuse_map_topic defaultTrue/arg namescan_topic default/scan/ arg nameinitial_pose_x default-0.5/arg nameinitial_pose_y default0.0/arg nameinitial_pose_a default0.0/arg nameodom_frame_id defaultodom/arg namebase_frame_id defaultbase_footprint/arg nameglobal_frame_id defaultmap/node pkgamcl typeamcl nameamclparam nameuse_map_topic value$(arg use_map_topic)/!-- Publish scans from best pose at a max of 10 Hz --param nameodom_model_type valuediff/ !-- 里程计模式为差分 --param nameodom_alpha5 value0.1/param namegui_publish_rate value10.0/param namelaser_max_beams value810/param namelaser_max_range value-1/param namemin_particles value500/param namemax_particles value5000/param namekld_err value0.05/param namekld_z value0.99/param nameodom_alpha1 value0.2/param nameodom_alpha2 value0.2/!-- translation std dev, m --param nameodom_alpha3 value0.2/param nameodom_alpha4 value0.2/param namelaser_z_hit value0.5/param namelaser_z_short value0.05/param namelaser_z_max value0.05/param namelaser_z_rand value0.5/param namelaser_sigma_hit value0.2/param namelaser_lambda_short value0.1/param namelaser_model_type valuelikelihood_field/!-- param namelaser_model_type valuebeam/ --param namelaser_likelihood_max_dist value2.0/param nameupdate_min_d value0.1/param nameupdate_min_a value0.2/param nameodom_frame_id value$(arg odom_frame_id)/ !-- 里程计坐标系 --param namebase_frame_id value$(arg base_frame_id)/ !-- 添加机器人基坐标系 --param nameglobal_frame_id value$(arg global_frame_id)/!-- 添加地图坐标系 --param nameresample_interval value1/!-- Increase tolerance because the computer can get quite busy --param nametransform_tolerance value1.0/param namerecovery_alpha_slow value0.0/param namerecovery_alpha_fast value0.0/param nameinitial_pose_x value$(arg initial_pose_x)/param nameinitial_pose_y value$(arg initial_pose_y)/param nameinitial_pose_a value$(arg initial_pose_a)/remap from/scan to$(arg scan_topic)/remap from/tf_static to/tf_static//node/launch