;\n <;param name=\"robot_description\" textfile=\"$(find 包名)/urdf/urdf/demo01.urdf.urdf\" />;\n <;!-- 启动 rviz -->;\n <;node pkg=\"rviz\" type=\"rviz\" name=\"rviz\" />;\n<;/launch>;\n\n```\n\n#####
4.在 Rviz 中显示机器人模型\n\n\n\n#####
5.优化 rviz 启动\n\n重复启动`launch`文件时,Rviz 之前的组件配置信息不会自动保存,需要重复执行步骤4的操作,为了方便使用,需要保存配置,在`file->;save config as`保存在之前的config文件夹中。最后在launch文件中添加即可。\n\n```\n<;launch>;\n <;param name=\"robot_description\" textfile=\"$(find 包名)/urdf/urdf/urdf01_HelloWorld.urdf\" />;\n <;node pkg=\"rviz\" type=\"rviz\" name=\"rviz\" args=\"-d $(find 报名)/config/rviz/show_mycar.rviz\" />;\n<;/launch>;\n\n```\n\n####
3、URDF语法学习\n\n> \nhttps://wiki.ros.org/urdf/XML\n\n\n#####
robot标签\n\n#####
link标签\n\nurdf 中的 link 标签用于描述机器人某个部件(也即刚体部分)的外观和物理属性。比如: 机器人底座、轮子、激光雷达、摄像头…每一个部件都对应一个 link, 在 link 标签内,可以设计该部件的形状、尺寸、颜色、惯性矩阵、碰撞参数等一系列属性\n\n\n\n```\n<;!-- 举例,执行需要通过launch-->;\n<;robot name=\"mycar\">;\n <;link name=\"base_link\">;\n <;visual>;\n <;!-- 形状 -->;\n <;geometry>;\n <;!-- 长方体的长宽高 -->;\n <;!-- <;box size=\"0.5 0.3 0.1\" />; -->;\n <;!-- 圆柱,半径和长度 -->;\n <;!-- <;cylinder radius=\"0.5\" length=\"0.1\" />; -->;\n <;!-- 球体,半径-->;\n <;!-- <;sphere radius=\"0.3\" />; -->;\n <;mesh filename=\"package://urdf01_rviz/meshes/autolabor_mini.stl\"/>;\n <;/geometry>;\n\n <;!-- xyz坐标 rpy翻滚俯仰与偏航角度(3.14=180度 1.57=90度) -->;\n <;origin xyz=\"0 0 0\" rpy=\"1.57 0 0\" />;\n <;!-- 颜色: r=red g=green b=blue a=alpha -->;\n <;material name=\"black\">;\n <;color rgba=\"0.7 0.5 0 0.5\" />;\n <;/material>;\n <;/visual>;\n <;/link>;\n<;/robot>;\n\n```\n\n#####
joint\n\nurdf 中的 joint 标签用于描述机器人关节的运动学和动力学属性,还可以指定关节运动的安全极限,机器人的两个部件(分别称之为 parent link 与 child link)以\"关节\"的形式相连接,不同的关节有不同的运动形式: 旋转、滑动、固定、旋转速度、旋转角度限制…,比如:安装在底座上的轮子可以360度旋转,而摄像头则可能是完全固定在底座上。\n\n\n\n**子级标签**\n\n**实例**\n\n创建`demo03_joint.urdf`\n\n```\n<;robot name=\"mycar\">;\n <;link name=\"base_footprint\">;\n <;visual>;\n <;geometry>;\n <;sphere radius=\"0.001\" />;\n <;/geometry>;\n <;/visual>;\n <;/link>;\n <;!-- 底盘 -->;\n <;link name=\"base_link\">;\n <;visual>;\n <;geometry>;\n <;box size=\"0.5 0.2 0.1\" />;\n <;/geometry>;\n <;origin xyz=\"0 0 0\" rpy=\"0 0 0\" />;\n <;material name=\"blue\">;\n <;color rgba=\"0 0 1.0 0.5\" />;\n <;/material>;\n <;/visual>;\n <;/link>;\n <;!-- 摄像头 -->;\n <;link name=\"camera\">;\n <;visual>;\n <;geometry>;\n <;box size=\"0.02 0.05 0.05\" />;\n <;/geometry>;\n <;origin xyz=\"0 0 0\" rpy=\"0 0 0\" />;\n <;material name=\"red\">;\n <;color rgba=\"1 0 0 0.5\" />;\n <;/material>;\n <;/visual>;\n <;/link>;\n <;joint name=\"link2foot\" type=\"fixed\">;\n <;parent link=\"base_footprint\"/>;\n <;child link=\"base_link\" />;\n <;!-- 需要计算两个 link 的物理中心之间的偏移量 -->;\n <;origin xyz=\"0 0 0.075\" rpy=\"0 0 0\" />;\n <;/joint>;\n <;!-- 关节 -->;\n <;joint name=\"camera2baselink\" type=\"continuous\">;\n <;parent link=\"base_link\"/>;\n <;child link=\"camera\" />;\n <;!-- 需要计算两个 link 的物理中心之间的偏移量 -->;\n <;origin xyz=\"0.2 0 0.075\" rpy=\"0 0 0\" />;\n <;axis xyz=\"0 0 1\" />;\n <;/joint>;\n<;/robot>;\n\n```\n\n创建`demo03_joint.launch`\n\n```\n<;launch>;\n <;!-- 设置参数 -->;\n <;param name=\"robot_description\" textfile=\"$(find urdf01_rviz)/urdf/urdf/demo03_joint.urdf\" />;\n\n <;!-- 启动 rviz -->;\n <;node pkg=\"rviz\" type=\"rviz\" name=\"rviz\" args=\"-d $(find urdf01_rviz)/config/show_mycar.rviz\"/>;\n\n <;!-- 添加关节状态发布节点 -->;\n <;node pkg=\"joint_state_publisher\" type=\"joint_state_publisher\" name=\"joint_state_publisher\" />;\n <;!-- 添加机器人状态发布节点 -->;\n <;node pkg=\"robot_state_publisher\" type=\"robot_state_publisher\" name=\"robot_state_publisher\" />;\n <;!-- 可选:用于控制关节运动的节点 -->;\n <;node pkg=\"joint_state_publisher_gui\" type=\"joint_state_publisher_gui\" name=\"joint_state_publisher_gui\" />;\n<;/launch>;\n\n```\n\n#####
URDF工具\n\n在 ROS 中,提供了一些工具来方便 URDF 文件的编写,比如在文件所在路径运行:\n\n```\n#检查复杂的 urdf 文件是否存在语法问题\ncheck_urdf xxx.urdf\n#查看 urdf 模型结构,显示不同 link 的层级关系\nurdf_to_graphiz xxx.urdf\n#查看生成的pdf\nevince xxx.pdf\n\n```\n\n工具之前,首先需要安装,安装命令:`sudo apt install liburdfdom-tools`\n\n####
4、URDF之xacro\n\n> \nXacro 是 XML Macros 的缩写,Xacro 是一种 XML 宏语言,是可编程的 XML。通过封装固定的逻辑,将逻辑中需要的可变的数据以参数的方式暴露出去,从而提高代码复用率以及程序的安全性。\n参考文档:http://wiki.ros.org/xacro\n\n\n#####
1、快速体验\n\n在功能包下的`urdf->;xacro`目录下新建`demo01_urdf.xacro`\n\n```\n<;robot name=\"mycar\" xmlns:xacro=\"http://wiki.ros.org/xacro\">;\n <;!-- 属性封装 -->;\n <;xacro:property name=\"wheel_radius\" value=\"0.0325\" />;\n <;xacro:property name=\"wheel_length\" value=\"0.0015\" />;\n <;xacro:property name=\"PI\" value=\"3.1415927\" />;\n <;xacro:property name=\"base_link_length\" value=\"0.08\" />;\n <;xacro:property name=\"lidi_space\" value=\"0.015\" />;\n <;!-- 宏 -->;\n <;xacro:macro name=\"wheel_func\" params=\"wheel_name flag\" >;\n <;link name=\"${wheel_name}_wheel\">;\n <;visual>;\n <;geometry>;\n <;cylinder radius=\"${wheel_radius}\" length=\"${wheel_length}\" />;\n <;/geometry>;\n\n <;origin xyz=\"0 0 0\" rpy=\"${PI / 2} 0 0\" />;\n\n <;material name=\"wheel_color\">;\n <;color rgba=\"0 0 0 0.3\" />;\n <;/material>;\n <;/visual>;\n <;/link>;\n <;!-- 3-2.joint -->;\n <;joint name=\"${wheel_name}2link\" type=\"continuous\">;\n <;parent link=\"base_link\" />;\n <;child link=\"${wheel_name}_wheel\" />;\n <;!-- \n x 无偏移\n y 车体半径\n z z= 车体高度 / 2 + 离地间距 - 车轮半径\n -->;\n <;origin xyz=\"0 ${0.1 * flag} ${(base_link_length / 2 + lidi_space - wheel_radius) * -1}\" rpy=\"0 0 0\" />;\n <;axis xyz=\"0 1 0\" />;\n <;/joint>;\n\n <;/xacro:macro>;\n <;xacro:wheel_func wheel_name=\"left\" flag=\"1\" />;\n <;xacro:wheel_func wheel_name=\"right\" flag=\"-1\" />;\n<;/robot>;\n\n```\n\n最后命令行进入 xacro文件 所属目录,执行:`rosrun xacro xacro xxx.xacro >; xxx.urdf`, 会将 xacro 文件解析为 urdf 文件\n\n#####
2、xacro语法学习\n\n**属性与算数运算**\n\n用于封装 URDF 中的一些字段\n\n```\n<;!--属性定义-->;\n<;xacro:property name=\"xxxx\" value=\"yyyy\" />;\n<;!--属性调用-->;\n${属性名称}\n<;!--算数运算-->;\n${数学表达式}\n${PI / 2}\n\n```\n\n**宏**\n\n类似于函数实现,提高代码复用率,优化代码结构,提高安全性\n\n```\n<;!--宏定义-->;\n<;xacro:macro name=\"宏名称\" params=\"参数列表(多参数之间使用空格分隔)\">;\n .....\n 参数调用格式: ${参数名}\n<;/xacro:macro>;\n<;!--宏调用-->;\n<;xacro:宏名称 参数1=xxx 参数2=xxx/>;\n\n```\n\n**文件包含**\n\n机器人由多部件组成,不同部件可能封装为单独的 xacro 文件,最后再将不同的文件集成,组合为完整机器人\n\n```\n<;robot name=\"xxx\" xmlns:xacro=\"http://wiki.ros.org/xacro\">;\n <;xacro:include filename=\"my_base.xacro\" />;\n <;xacro:include filename=\"my_camera.xacro\" />;\n <;xacro:include filename=\"my_laser.xacro\" />;\n ....\n<;/robot>;\n\n```\n\n#####
3、xacro模型实现\n\n在xacro文件中\n\n```\n<;!--\n 使用 xacro 优化 URDF 版的小车底盘实现:\n\n 实现思路:\n 1.将一些常量、变量封装为 xacro:property\n 比如:PI 值、小车底盘半径、离地间距、车轮半径、宽度 ....\n 2.使用 宏 封装驱动轮以及支撑轮实现,调用相关宏生成驱动轮与支撑轮\n\n-->;\n<;!-- 根标签,必须声明 xmlns:xacro -->;\n<;robot name=\"my_base\" xmlns:xacro=\"http://www.ros.org/wiki/xacro\">;\n <;!-- 封装变量、常量 -->;\n <;xacro:property name=\"PI\" value=\"3.141\"/>;\n <;!-- 宏:黑色设置 -->;\n <;material name=\"black\">;\n <;color rgba=\"0.0 0.0 0.0 1.0\" />;\n <;/material>;\n <;!-- 底盘属性 -->;\n <;xacro:property name=\"base_footprint_radius\" value=\"0.001\" />; <;!-- base_footprint 半径 -->;\n <;xacro:property name=\"base_link_radius\" value=\"0.1\" />; <;!-- base_link 半径 -->;\n <;xacro:property name=\"base_link_length\" value=\"0.08\" />; <;!-- base_link 长 -->;\n <;xacro:property name=\"earth_space\" value=\"0.015\" />; <;!-- 离地间距 -->;\n\n <;!-- 底盘 -->;\n <;link name=\"base_footprint\">;\n <;visual>;\n <;geometry>;\n <;sphere radius=\"${base_footprint_radius}\" />;\n <;/geometry>;\n <;/visual>;\n <;/link>;\n\n <;link name=\"base_link\">;\n <;visual>;\n <;geometry>;\n <;cylinder radius=\"${base_link_radius}\" length=\"${base_link_length}\" />;\n <;/geometry>;\n <;origin xyz=\"0 0 0\" rpy=\"0 0 0\" />;\n <;material name=\"yellow\">;\n <;color rgba=\"0.5 0.3 0.0 0.5\" />;\n <;/material>;\n <;/visual>;\n <;/link>;\n\n <;joint name=\"base_link2base_footprint\" type=\"fixed\">;\n <;parent link=\"base_footprint\" />;\n <;child link=\"base_link\" />;\n <;origin xyz=\"0 0 ${earth_space + base_link_length / 2 }\" />;\n <;/joint>;\n\n <;!-- 驱动轮 -->;\n <;!-- 驱动轮属性 -->;\n <;xacro:property name=\"wheel_radius\" value=\"0.0325\" />;<;!-- 半径 -->;\n <;xacro:property name=\"wheel_length\" value=\"0.015\" />;<;!-- 宽度 -->;\n <;!-- 驱动轮宏实现 -->;\n <;xacro:macro name=\"add_wheels\" params=\"name flag\">;\n <;link name=\"${name}_wheel\">;\n <;visual>;\n <;geometry>;\n <;cylinder radius=\"${wheel_radius}\" length=\"${wheel_length}\" />;\n <;/geometry>;\n <;origin xyz=\"0.0 0.0 0.0\" rpy=\"${PI / 2} 0.0 0.0\" />;\n <;material name=\"black\" />;\n <;/visual>;\n <;/link>;\n\n <;joint name=\"${name}_wheel2base_link\" type=\"continuous\">;\n <;parent link=\"base_link\" />;\n <;child link=\"${name}_wheel\" />;\n <;origin xyz=\"0 ${flag * base_link_radius} ${-(earth_space + base_link_length / 2 - wheel_radius) }\" />;\n <;axis xyz=\"0 1 0\" />;\n <;/joint>;\n <;/xacro:macro>;\n <;xacro:add_wheels name=\"left\" flag=\"1\" />;\n <;xacro:add_wheels name=\"right\" flag=\"-1\" />;\n <;!-- 支撑轮 -->;\n <;!-- 支撑轮属性 -->;\n <;xacro:property name=\"support_wheel_radius\" value=\"0.0075\" />; <;!-- 支撑轮半径 -->;\n\n <;!-- 支撑轮宏 -->;\n <;xacro:macro name=\"add_support_wheel\" params=\"name flag\" >;\n <;link name=\"${name}_wheel\">;\n <;visual>;\n <;geometry>;\n <;sphere radius=\"${support_wheel_radius}\" />;\n <;/geometry>;\n <;origin xyz=\"0 0 0\" rpy=\"0 0 0\" />;\n <;material name=\"black\" />;\n <;/visual>;\n <;/link>;\n\n <;joint name=\"${name}_wheel2base_link\" type=\"continuous\">;\n <;parent link=\"base_link\" />;\n <;child link=\"${name}_wheel\" />;\n <;origin xyz=\"${flag * (base_link_radius - support_wheel_radius)} 0 ${-(base_link_length / 2 + earth_space / 2)}\" />;\n <;axis xyz=\"1 1 1\" />;\n <;/joint>;\n <;/xacro:macro>;\n <;xacro:add_support_wheel name=\"front\" flag=\"1\" />;\n <;xacro:add_support_wheel name=\"back\" flag=\"-1\" />;\n<;/robot>;\n\n```\n\nlaunch文件,注意文件名修改\n\n```\n<;launch>;\n <;param name=\"robot_description\" command=\"$(find xacro)/xacro $(find urdf01_rviz)/urdf/xacro/demo05_car_base.urdf.xacro\" />;\n <;node pkg=\"rviz\" type=\"rviz\" name=\"rviz\" args=\"-d $(find urdf01_rviz)/config/show_mycar.rviz\" />;\n <;node pkg=\"joint_state_publisher\" type=\"joint_state_publisher\" name=\"joint_state_publisher\" output=\"screen\" />;\n <;node pkg=\"robot_state_publisher\" type=\"robot_state_publisher\" name=\"robot_state_publisher\" output=\"screen\" />;\n <;node pkg=\"joint_state_publisher_gui\" type=\"joint_state_publisher_gui\" name=\"joint_state_publisher_gui\" output=\"screen\" />;\n<;/launch>;\n\n```\n\n####
5、Rviz控制机器人运动(arbotix)\n\n**实现流程:**\n1. 安装 Arbotix1. 创建新功能包,准备机器人 urdf、xacro 文件1. 添加 Arbotix 配置文件1. 编写 launch 文件配置 Arbotix1. 启动 launch 文件并控制机器人模型运动\n**安装**\n\n```\nsudo apt install ros-noetic-arbotix\n\n```\n\n**添加 arbotix 所需配置文件**\n\n```\n# 该文件是控制器配置,一个机器人模型可能有多个控制器,比如: 底盘、机械臂、夹持器(机械手)....\n# 因此,根 name 是 controller\ncontrollers: {\n # 单控制器设置\n base_controller: {\n #类型: 差速控制器\n type: diff_controller,\n #参考坐标\n base_frame_id: base_footprint, \n #两个轮子之间的间距\n base_width: 0.2,\n #控制频率\n ticks_meter: 2000, \n #PID控制参数,使机器人车轮快速达到预期速度\n Kp: 12, \n Kd: 12, \n Ki: 0, \n Ko: 50, \n #加速限制\n accel_limit: 1.0 \n }\n}\n\n```\n\n**launch 示例代码**\n\n```\n<;launch>;\n <;param name=\"robot_description\" command=\"$(find xacro)/xacro $(find urdf01_rviz)/urdf/xacro/car.urdf.xacro\" />;\n\n <;node pkg=\"rviz\" type=\"rviz\" name=\"rviz\" args=\"-d $(find urdf01_rviz)/config/show_mycar.rviz\" />;\n <;node pkg=\"joint_state_publisher\" type=\"joint_state_publisher\" name=\"joint_state_publisher\" output=\"screen\" />;\n <;node pkg=\"robot_state_publisher\" type=\"robot_state_publisher\" name=\"robot_state_publisher\" output=\"screen\" />;\n <;!-- <; node>; 调用了 arbotix_python 功能包下的 arbotix_driver 节点 -->;\n <;node name=\"arbotix\" pkg=\"arbotix_python\" type=\"arbotix_driver\" output=\"screen\">;\n <;!--<; rosparam>; arbotix 驱动机器人运行时,需要获取机器人信息,可以通过 file 加载配置文件-->;\n <;rosparam file=\"$(find urdf01_rviz)/config/control.yml\" command=\"load\" />;\n <;!--<; param>; 在仿真环境下,需要配置 sim 为 true-->;\n <;param name=\"sim\" value=\"true\" />;\n <;/node>;\n<;/launch>;\n\n```\n\n启动launch后,命令行输入`rostopic pub -r 10 /cmd_vel geometry_msgs/Twist \'{linear: {x: 0.2, y: 0, z: 0}, angular: {x: 0, y: 0, z: 0.5}}\'`机器人即可成功启动\n\n####
6、URDF集成Gazebo\n\n#####
1、快速体验\n\n**1.创建功能包**\n\n创建新功能包,导入依赖包: urdf、xacro、gazebo_ros、gazebo_ros_control、gazebo_plugins\n\n**2.编写URDF文件**\n\n```\n<;!-- \n 创建一个机器人模型(盒状即可),显示在 Gazebo 中 \n-->;\n<;robot name=\"mycar\">;\n <;link name=\"base_link\">;\n <;visual>;\n <;geometry>;\n <;box size=\"0.5 0.2 0.1\" />;\n <;/geometry>;\n <;origin xyz=\"0.0 0.0 0.0\" rpy=\"0.0 0.0 0.0\" />;\n <;material name=\"yellow\">;\n <;color rgba=\"0.5 0.3 0.0 1\" />;\n <;/material>;\n <;/visual>;\n <;collision>;\n <;geometry>;\n <;box size=\"0.5 0.2 0.1\" />;\n <;/geometry>;\n <;origin xyz=\"0.0 0.0 0.0\" rpy=\"0.0 0.0 0.0\" />;\n <;/collision>;\n <;inertial>;\n <;origin xyz=\"0 0 0\" />;\n <;mass value=\"6\" />;\n <;inertia ixx=\"1\" ixy=\"0\" ixz=\"0\" iyy=\"1\" iyz=\"0\" izz=\"1\" />;\n <;/inertial>;\n <;/link>;\n <;gazebo reference=\"base_link\">;\n <;material>;Gazebo/Black<;/material>;\n <;/gazebo>;\n\n<;/robot>;\n\n```\n\n注意, 当 URDF 需要与 Gazebo 集成时,和 Rviz 有明显区别:\n\n1.必须使用 collision 标签,因为既然是仿真环境,那么必然涉及到碰撞检测,collision 提供碰撞检测的依据。\n\n2.必须使用 inertial 标签,此标签标注了当前机器人某个刚体部分的惯性矩阵,用于一些力学相关的仿真计算。\n\n3.颜色设置,也需要重新使用 gazebo 标签标注,因为之前的颜色设置为了方便调试包含透明度,仿真环境下没有此选项。\n\n**3.启动Gazebo并显示模型**\n\nlaunch 文件实现:\n\n```\n<;launch>;\n <;!-- 将 Urdf 文件的内容加载到参数服务器 -->;\n <;param name=\"robot_description\" textfile=\"$(find urdf02_gazebo)/urdf/demo01_hello.urdf\" />;\n <;!-- 启动 gazebo -->;\n <;include file=\"$(find gazebo_ros)/launch/empty_world.launch\" />;\n <;!-- 在 gazebo 中显示机器人模型 -->;\n <;node pkg=\"gazebo_ros\" type=\"spawn_model\" name=\"model\" args=\"-urdf -model mycar -param robot_description\" />;\n <;!-- \n 在 Gazebo 中加载一个机器人模型,该功能由 gazebo_ros 下的 spawn_model 提供:\n -urdf 加载的是 urdf 文件\n -model mycar 模型名称是 mycar\n -param robot_description 从参数 robot_description 中载入模型\n -x 模型载入的 x 坐标\n -y 模型载入的 y 坐标\n -z 模型载入的 z 坐标\n-->;\n<;/launch>;\n\n```\n\n#####
2、gazebo相关设置\n\n**1.collision**\n\n如果机器人link是标准的几何体形状,和link的 visual 属性设置一致即可。\n\n**2.inertial**\n\n惯性矩阵的设置需要结合link的质量与外形参数动态生成,标准的球体、圆柱与立方体的惯性矩阵公式如下(已经封装为 xacro 实现):\n\n球体惯性矩阵\n\n```\n<;!-- Macro for inertia matrix -->;\n <;xacro:macro name=\"sphere_inertial_matrix\" params=\"m r\">;\n <;inertial>;\n <;mass value=\"${m}\" />;\n <;inertia ixx=\"${2*m*r*r/5}\" ixy=\"0\" ixz=\"0\"\n iyy=\"${2*m*r*r/5}\" iyz=\"0\" \n izz=\"${2*m*r*r/5}\" />;\n <;/inertial>;\n <;/xacro:macro>;\n\n```\n\n圆柱惯性矩阵\n\n```\n<;xacro:macro name=\"cylinder_inertial_matrix\" params=\"m r h\">;\n <;inertial>;\n <;mass value=\"${m}\" />;\n <;inertia ixx=\"${m*(3*r*r+h*h)/12}\" ixy = \"0\" ixz = \"0\"\n iyy=\"${m*(3*r*r+h*h)/12}\" iyz = \"0\"\n izz=\"${m*r*r/2}\" />; \n <;/inertial>;\n <;/xacro:macro>;\n\n```\n\n立方体惯性矩阵\n\n```\n <;xacro:macro name=\"Box_inertial_matrix\" params=\"m l w h\">;\n <;inertial>;\n <;mass value=\"${m}\" />;\n <;inertia ixx=\"${m*(h*h + l*l)/12}\" ixy = \"0\" ixz = \"0\"\n iyy=\"${m*(w*w + l*l)/12}\" iyz= \"0\"\n izz=\"${m*(w*w + h*h)/12}\" />;\n <;/inertial>;\n <;/xacro:macro>;\n\n```\n\n需要注意的是,原则上,除了 base_footprint 外,机器人的每个刚体部分都需要设置惯性矩阵,且惯性矩阵必须经计算得出,如果随意定义刚体部分的惯性矩阵,那么可能会导致机器人在 Gazebo 中出现抖动,移动等现象。\n\n**3.颜色设置**\n\n在 gazebo 中显示 link 的颜色,必须要使用指定的标签:\n\n```\n<;gazebo reference=\"link节点名称\">;\n <;material>;Gazebo/Blue<;/material>;\n<;/gazebo>;\n\n```\n\n**PS:**material 标签中,设置的值区分大小写,颜色可以设置为 Red Blue Green Black …\n\n#####
3、仿真环境的搭建与使用\n\n对于使用已搭建完的世界,在空世界中包含world文件即可\n\n```\n<;include file=\"$(find gazebo_ros)/launch/empty_world.launch\">;\n <;arg name=\"world_name\" value=\"$(find demo02_urdf_gazebo)/worlds/hello.world\" />;\n<;/include>;\n\n```\n\n对于环境的搭建(要占用大量电脑资源)\n\n####
7、URDF、Rviz和Gazebo综合使用\n\n> \n关于URDF(Xacro)、Rviz 和 Gazebo 三者的关系。 URDF 用于创建机器人模型、Rviz 可以显示机器人感知到的环境信息,Gazebo 用于仿真,可以模拟外界环境,以及机器人的一些传感器
参考文档: http://gazebosim.org/tutorials?tut=ros_gzplugins\n\n\n###
八、机器人导航\n\n> \nhttp://wiki.ros.org/navigation\n\n\n####
1、导航概述\n\n全局地图、自身定位、路径规划、运动控制、环境感知\n\n####
2、导航实现\n\n#####
1、准备工作\n\n最后创建新功能包,导入依赖`gmapping map_server amcl move_base`\n\n#####
2、SLAM建图\n\n> \n官方文档\n\n\n创建launch文件\n\n```\n<;launch>;\n<;param name=\"use_sim_time\" value=\"true\"/>;\n <;node pkg=\"gmapping\" type=\"slam_gmapping\" name=\"slam_gmapping\" output=\"screen\">;\n <;remap from=\"scan\" to=\"scan\"/>;<;!-- 雷达话题 -->;\n <;param name=\"base_frame\" value=\"base_footprint\"/>;<;!--底盘坐标系-->;\n <;param name=\"odom_frame\" value=\"odom\"/>; <;!--里程计坐标系-->;\n <;param name=\"map_update_interval\" value=\"5.0\"/>;\n <;param name=\"maxUrange\" value=\"16.0\"/>;\n <;param name=\"sigma\" value=\"0.05\"/>;\n <;param name=\"kernelSize\" value=\"1\"/>;\n <;param name=\"lstep\" value=\"0.05\"/>;\n <;param name=\"astep\" value=\"0.05\"/>;\n <;param name=\"iterations\" value=\"5\"/>;\n <;param name=\"lsigma\" value=\"0.075\"/>;\n <;param name=\"ogain\" value=\"3.0\"/>;\n <;param name=\"lskip\" value=\"0\"/>;\n <;param name=\"srr\" value=\"0.1\"/>;\n <;param name=\"srt\" value=\"0.2\"/>;\n <;param name=\"str\" value=\"0.1\"/>;\n <;param name=\"stt\" value=\"0.2\"/>;\n <;param name=\"linearUpdate\" value=\"1.0\"/>;\n <;param name=\"angularUpdate\" value=\"0.5\"/>;\n <;param name=\"temporalUpdate\" value=\"3.0\"/>;\n <;param name=\"resampleThreshold\" value=\"0.5\"/>;\n <;param name=\"particles\" value=\"30\"/>;\n <;param name=\"xmin\" value=\"-50.0\"/>;\n <;param name=\"ymin\" value=\"-50.0\"/>;\n <;param name=\"xmax\" value=\"50.0\"/>;\n <;param name=\"ymax\" value=\"50.0\"/>;\n <;param name=\"delta\" value=\"0.05\"/>;\n <;param name=\"llsamplerange\" value=\"0.01\"/>;\n <;param name=\"llsamplestep\" value=\"0.01\"/>;\n <;param name=\"lasamplerange\" value=\"0.005\"/>;\n <;param name=\"lasamplestep\" value=\"0.005\"/>;\n <;/node>;\n\n <;node pkg=\"joint_state_publisher\" name=\"joint_state_publisher\" type=\"joint_state_publisher\" />;\n <;node pkg=\"robot_state_publisher\" name=\"robot_state_publisher\" type=\"robot_state_publisher\" />;\n\n <;node pkg=\"rviz\" type=\"rviz\" name=\"rviz\" />;\n <;!-- 可以保存 rviz 配置并后期直接使用-->;\n <;!--\n <;node pkg=\"rviz\" type=\"rviz\" name=\"rviz\" args=\"-d $(find my_nav_sum)/rviz/gmapping.rviz\"/>;\n -->;\n<;/launch>;\n\n```\n\n首先启动 Gazebo 仿真环境\n\n再启动地图绘制的 launch 文件:\n\n然后启动键盘键盘控制节点,用于控制机器人运动建图\n\n```\nrosrun teleop_twist_keyboard teleop_twist_keyboard.py\n\n```\n\n最后在 rviz 中添加组件,显示栅格地图\n\n####
3、地图服务\n\n依次启动仿真环境,键盘控制节点与SLAM节点,绘制地图后启动保存地图的launch文件,即可保存地图信息\n\n```\n<;launch>;\n <;arg name=\"filename\" value=\"$(find nav_demo)/map/nav\" />;\n <;node name=\"map_save\" pkg=\"map_server\" type=\"map_saver\" args=\"-f $(arg filename)\" />;\n<;/launch>;\n\n```\n\n对于地图的获取,启动新的launch文件,即可发布map地图信息了,之后只需要在rviz订阅/map即可\n\n```\n<;launch>;\n <;!-- 设置地图的配置文件 -->;\n <;arg name=\"map\" default=\"nav.yaml\" />;\n <;!-- 运行地图服务器,并且加载设置的地图-->;\n <;node name=\"map_server\" pkg=\"map_server\" type=\"map_server\" args=\"$(find nav_demo)/map/$(arg map)\"/>;\n<;/launch>;\n\n```\n\nnav.yaml部分详解\n\n```\n#1.声明地图图片资源的路径\nimage: /home/shawn/catkin_demo/src/nav_demo/map/nav.pgm\n#2.地图刻度尺单位是米/像素\nresolution: 0.050000\n#3.地图的位姿(相对于rViz中的原点的位姿)\norigin: [-50.000000,-50.000000,0.0]\n#4.占用阈值\noccupied thresh: 0.65\n#5空闲间值\nfree thresh: 0.196\n#6.取反\nnegate: 0\n\n```\n\n####
4、定位\n\n编写launch文件\n\n```\n<;launch>;\n<;node pkg=\"amcl\" type=\"amcl\" name=\"amcl\" output=\"screen\">;\n <;!-- Publish scans from best pose at a max of 10 Hz -->;\n <;param name=\"odom_model_type\" value=\"diff\"/>;<;!-- 里程计模式为差分 -->;\n <;param name=\"odom_alpha5\" value=\"0.1\"/>;\n <;param name=\"transform_tolerance\" value=\"0.2\" />;\n <;param name=\"gui_publish_rate\" value=\"10.0\"/>;\n <;param name=\"laser_max_beams\" value=\"30\"/>;\n <;param name=\"min_particles\" value=\"500\"/>;\n <;param name=\"max_particles\" value=\"5000\"/>;\n <;param name=\"kld_err\" value=\"0.05\"/>;\n <;param name=\"kld_z\" value=\"0.99\"/>;\n <;param name=\"odom_alpha1\" value=\"0.2\"/>;\n <;param name=\"odom_alpha2\" value=\"0.2\"/>;\n <;!-- translation std dev, m -->;\n <;param name=\"odom_alpha3\" value=\"0.8\"/>;\n <;param name=\"odom_alpha4\" value=\"0.2\"/>;\n <;param name=\"laser_z_hit\" value=\"0.5\"/>;\n <;param name=\"laser_z_short\" value=\"0.05\"/>;\n <;param name=\"laser_z_max\" value=\"0.05\"/>;\n <;param name=\"laser_z_rand\" value=\"0.5\"/>;\n <;param name=\"laser_sigma_hit\" value=\"0.2\"/>;\n <;param name=\"laser_lambda_short\" value=\"0.1\"/>;\n <;param name=\"laser_lambda_short\" value=\"0.1\"/>;\n <;param name=\"laser_model_type\" value=\"likelihood_field\"/>;\n <;!-- <;param name=\"laser_model_type\" value=\"beam\"/>; -->;\n <;param name=\"laser_likelihood_max_dist\" value=\"2.0\"/>;\n <;param name=\"update_min_d\" value=\"0.2\"/>;\n <;param name=\"update_min_a\" value=\"0.5\"/>;\n\n <;param name=\"odom_frame_id\" value=\"odom\"/>;<;!-- 里程计坐标系 -->;\n <;param name=\"base_frame_id\" value=\"base_footprint\"/>;<;!-- 添加机器人基坐标系 -->;\n <;param name=\"global_frame_id\" value=\"map\"/>;<;!-- 添加地图坐标系 -->;\n\n <;param name=\"resample_interval\" value=\"1\"/>;\n <;param name=\"transform_tolerance\" value=\"0.1\"/>;\n <;param name=\"recovery_alpha_slow\" value=\"0.0\"/>;\n <;param name=\"recovery_alpha_fast\" value=\"0.0\"/>;\n<;/node>;\n<;/launch>;\n\n```\n\n测试launch文件\n\n```\n<;launch>;\n <;!-- 设置地图的配置文件 -->;\n <;arg name=\"map\" default=\"nav.yaml\" />;\n <;!-- 运行地图服务器,并且加载设置的地图-->;\n <;node name=\"map_server\" pkg=\"map_server\" type=\"map_server\" args=\"$(find nav_demo)/map/$(arg map)\"/>;\n <;!-- 启动AMCL节点 -->;\n <;include file=\"$(find nav_demo)/launch/amcl.launch\" />;\n <;!-- 运行rviz -->;\n <;node pkg=\"rviz\" type=\"rviz\" name=\"rviz\"/>;\n<;/launch>;\n\n```\n\n######
执行\n\n1.先启动 Gazebo 仿真环境\n\n2.启动键盘控制节点:\n\n```\nrosrun teleop_twist_keyboard teleop_twist_keyboard.py\n\n```\n\n3.启动上一步中集成地图服务、amcl 与 rviz 的 launch 文件;\n\n4.在启动的 rviz 中,添加RobotModel、Map组件,分别显示机器人模型与地图,添加 posearray 插件,设置topic为particlecloud来显示 amcl 预估的当前机器人的位姿,箭头越是密集,说明当前机器人处于此位置的概率越高;\n\n####
5、路径规划\n\n创建`nav05_path.launch`文件\n\n```\n<;launch>;\n <;node pkg=\"move_base\" type=\"move_base\" respawn=\"false\" name=\"move_base\" output=\"screen\" clear_params=\"true\">;\n <;rosparam file=\"$(find nav_demo)/param/costmap_common_params.yaml\" command=\"load\" ns=\"local_costmap\" />;\n <;rosparam file=\"$(find nav_demo)/param/costmap_common_params.yaml\" command=\"load\" ns=\"global_costmap\" />;\n <;rosparam file=\"$(find nav_demo)/param/local_costmap_params.yaml\" command=\"load\" />;\n <;rosparam file=\"$(find nav_demo)/param/global_costmap_params.yaml\" command=\"load\" />;\n <;rosparam file=\"$(find nav_demo)/param/base_local_planner_params.yaml\" command=\"load\" />;\n <;/node>;\n<;/launch>;\n\n```\n\n**costmap_common_params.yaml**\n\n该文件是move_base 在全局路径规划与本地路径规划时调用的通用参数,包括:机器人的尺寸、距离障碍物的安全距离、传感器信息等。配置参考如下:\n\n```\n#机器人几何参,如果机器人是圆形,设置 robot_radius,如果是其他形状设置 footprint\nrobot_radius: 0.12 #圆形\n# footprint: [[-0.12, -0.12], [-0.12, 0.12], [0.12, 0.12], [0.12, -0.12]] #其他形状\n\nobstacle_range: 3.0 # 用于障碍物探测,比如: 值为 3.0,意味着检测到距离小于 3 米的障碍物时,就会引入代价地图\nraytrace_range: 3.5 # 用于清除障碍物,比如:值为 3.5,意味着清除代价地图中 3.5 米以外的障碍物\n\n\n#膨胀半径,扩展在碰撞区域以外的代价区域,使得机器人规划路径避开障碍物\ninflation_radius: 0.2\n#代价比例系数,越大则代价值越小\ncost_scaling_factor: 3.0\n\n#地图类型\nmap_type: costmap\n#导航包所需要的传感器\nobservation_sources: scan\n#对传感器的坐标系和数据进行配置。这个也会用于代价地图添加和清除障碍物。例如,你可以用激光雷达传感器用于在代价地图添加障碍物,再添加kinect用于导航和清除障碍物。\nscan: {sensor_frame: laser, data_type: LaserScan, topic: scan, marking: true, clearing: true}\n\n```\n\n**global_costmap_params.yaml**\n\n该文件用于全局代价地图参数设置:\n\n```\nglobal_costmap:\n global_frame: map #地图坐标系\n robot_base_frame: base_footprint #机器人坐标系\n # 以此实现坐标变换\n\n update_frequency: 1.0 #代价地图更新频率\n publish_frequency: 1.0 #代价地图的发布频率\n transform_tolerance: 0.5 #等待坐标变换发布信息的超时时间\n\n static_map: true # 是否使用一个地图或者地图服务器来初始化全局代价地图,如果不使用静态地图,这个参数为false.\n\n```\n\n**local_costmap_params.yaml**\n\n该文件用于局部代价地图参数设置:\n\n```\nlocal_costmap:\n global_frame: odom #里程计坐标系\n robot_base_frame: base_footprint #机器人坐标系\n\n update_frequency: 10.0 #代价地图更新频率\n publish_frequency: 10.0 #代价地图的发布频率\n transform_tolerance: 0.5 #等待坐标变换发布信息的超时时间\n\n static_map: false #不需要静态地图,可以提升导航效果\n rolling_window: true #是否使用动态窗口,默认为false,在静态的全局地图中,地图不会变化\n width: 3 # 局部地图宽度 单位是 m\n height: 3 # 局部地图高度 单位是 m\n resolution: 0.05 # 局部地图分辨率 单位是 m,一般与静态地图分辨率保持一致\n\n```\n\n**base_local_planner_params**\n\n基本的局部规划器参数配置,这个配置文件设定了机器人的最大和最小速度限制值,也设定了加速度的阈值。\n\n```\nTrajectoryPlannerROS:\n\n# Robot Configuration Parameters\n max_vel_x: 0.5 # X 方向最大速度\n min_vel_x: 0.1 # X 方向最小速速\n\n max_vel_theta: 1.0 # \n min_vel_theta: -1.0\n min_in_place_vel_theta: 1.0\n\n acc_lim_x: 1.0 # X 加速限制\n acc_lim_y: 0.0 # Y 加速限制\n acc_lim_theta: 0.6 # 角速度加速限制\n\n# Goal Tolerance Parameters,目标公差\n xy_goal_tolerance: 0.10\n yaw_goal_tolerance: 0.05\n\n# Differential-drive robot configuration\n# 是否是全向移动机器人\n holonomic_robot: false\n\n# Forward Simulation Parameters,前进模拟参数\n sim_time: 0.8\n vx_samples: 18\n vtheta_samples: 20\n sim_granularity: 0.05\n\n```\n\n**最后文件集成**\n\n运行仿真环境、运行launch文件\n\n```\n<;launch>;\n <;!-- 设置地图的配置文件 -->;\n <;arg name=\"map\" default=\"nav.yaml\" />;\n <;!-- 运行地图服务器,并且加载设置的地图-->;\n <;node name=\"map_server\" pkg=\"map_server\" type=\"map_server\" args=\"$(find nav_demo)/map/$(arg map)\"/>;\n <;!-- 启动AMCL节点 -->;\n <;include file=\"$(find nav_demo)/launch/nav04_amcl.launch\" />;\n <;!-- 运行move_base节点 -->;\n <;include file=\"$(find nav_demo)/launch/nav05_path.launch\" />;\n <;!-- 关节以及机器人状态发布节点 -->;\n <;node name=\"joint_state_publisher\" pkg=\"joint_state_publisher\" type=\"joint_state_publisher\" />;\n <;node name=\"robot_state_publisher\" pkg=\"robot_state_publisher\" type=\"robot_state_publisher\" />;\n <;!-- 运行rviz -->;\n <;node pkg=\"rviz\" type=\"rviz\" name=\"rviz\" args=\"-d $(find nav_demo)/config/nav.rviz\" />;\n<;/launch>;\n\n```\n\n####
6、导航与SLAM建图\n\n#####
1.编写launch文件\n\n当前launch文件实现,无需调用map_server的相关节点,只需要启动SLAM节点与move_base节点,示例内容如下:\n\n```\n<;launch>;\n <;!-- 启动SLAM节点 -->;\n <;include file=\"$(find nav_demo)/launch/nav01_slam.launch\" />;\n <;!-- 运行move_base节点 -->;\n <;include file=\"$(find nav_demo)/launch/nav05_path.launch\" />;\n <;!-- 运行rviz -->;\n <;!-- <;node pkg=\"rviz\" type=\"rviz\" name=\"rviz\" args=\"-d $(find nav_demo)/config/nav.rviz\" />; -->;\n<;/launch>;\n\n```\n\n#####
2.测试\n\n1.首先运行gazebo仿真环境;\n\n2.然后执行launch文件;\n\n3.在rviz中通过2D Nav Goal设置目标点,机器人开始自主移动并建图了;\n\n4.最后可以使用 map_server 保存地图。\n\n###
九、学习资料\n\nROS: https://www.ros.org
ROS Wiki: http://wiki.ros.org
ROSCon 2012~2019:https://roscon.ros.org
ROS Robots: https://robots.ros.org
Ubuntu Wiki: https://wiki.ubuntu.org.cn
古月居:http://www.guyuehome.com
古月居泡泡:https://www.guyuehome.com/Bubble
古月学院:https://class.guyuehome.com
如何学习ROS:
https://mp.weixin.qq.com/s/uYvGuiG-TlOalWUynR2Nzg
一起从零手写URDF模型:
https://class.guyuehome.com/detail/p5eleea4fe1e5c_lgm126Xn/6
如何从Solidworks导出URDF模型
https://class.guyuehome.com/detail/p5e32dce7906e0_6TqS7BwX/6
如何在Gazebo中实现移动机器人仿真:
https://class.guyuehome.com/detail/p_5eb2366befe4aE4rbNmXt/6
Movelt可视化配置及仿真指南
https://class.guyuehome.com/detail/p_5e71966b3fdfd_g4DpRGg9/6\n -->