因为都是一边学一边做,所以难免走一些弯路了,如果有什么错误希望各位指出来,谢谢
接着上次的思路,希望让添加的模型动起来,但连Gazebo官网上都是用urdf文件讲的……所以那还是用urdf文件吧
通过前面我们已经知道怎么让urdf文件形成的模型在gazebo里出现了(在launch文件中spawn一个),这一次希望它能动起来,基于一辆简单的“小车”模型吧,参考的这个项目以及官方教程。这个文件是已经完成的,还是从仅有模型形态的urdf文件开始,一步步来:
1. 添加<transmission>标签
这一步比较简单,就是需要在urdf文件的<robot>标签下添加与joint相应的<transimission>标签。
这个标签的作用是在joint上添加一个actuator(执行器),也很好理解,大致形式如下:
<transmission name="tran_SOME_JOINT"> <type>transmission_interface_SimpleTransmission</type> <joint name="SOME_JOINT"> <hardwareInterface>hardware_interface/VelocityJointInterface</hardwareInterface> </joint> <actuator name="ACTUATOR"> <hardwareInterface>hardware_interface/VelocityJointInterface</hardwareInterface> <mechanicalReduction>1</mechanicalReduction> </actuator> </transmission>
可以看到主要就是三部分的内容:type, joint和actuator
<type>表示transmission的类型
<joint>指明将在哪个joint上添加执行器,用name给出该joint的名字。另外,其中还包含一个<hardwareInterface>标签,用来指定一个支持的关节空间硬件接口。这句话是官方翻译过来的,感觉等于白说,还没仔细研究,不是很懂hardInterface是干啥的,留个坑
<actuator>表示连接到joint的执行器,name表示它的名字。包含<mechanicalReduction>表示减速比。
- 来自官方的几个说明:
- 如果在Gazebo里加载这个transmission,<joint>里的<hardwareInterface>的值应该是EffortJointInterface,而如果在RobotHW中加载,则该值应该是haedwareInterface/EffortJointInterface(当然不仅有EffortJointInterface,还有VelocityJointInterface, PositionJointInterface,或者自己写的类);
- <actuator>标签下的<mechanicalReduction>是可选项,而<hardwareInterface>在ROS Kinetic版本以后就不在这里出现了,而是在<joint>标签里,这个应该是一个bug,所以Gazebo官方里要求两个地方都写,不过我也在Kinetic中测试过,去掉之后也可以运行。
到此为止,相当于是模型部分弄完了,加的transimission也算是实际机器人的硬件部分,所以我就暂时把这以前的内容视为一大部分,接下来就是控制器部分,相当于软件部分。虽说我把以后的工作与前面分开来,但并不代表不再对urdf文件进行操作了,只是说从功能的上,我个人觉得这样划分更易于理解。
2. 添加gazebo_ros_control plugin
ROS里有个ros_control包,用于机器人的控制,相应的,在Gazebo里使用则需要在urdf文件中添加一个gazebo plugin:
<gazebo> <plugin name="gazebo_ros_control" filename="libgazebo_ros_control.so"> <robotNamespace>/MYROBOT</robotNamespace> </plugin> </gazebo>
默认使用这样就够了,但是我在运行的时候遇到了一个关于什么legacyNS的报错,查了一下,需要在<plugin>里面添加一条:
<legacyModeNS>true</legacyModeNS>
3. 新建一个ros_controls包
新建一个新ROS包
mkdir ~/catkin_ws cd ~/catkin_ws catkin_create_pkg MYROBOT_control controller_manager joint_state_controller robot_state_publisher cd MYROBOT_control mkdir config mkdir launch
新建.yaml配置文件
.yaml文件用于配置控制器的类型和PID参数(为啥一定是PID控制器?),MYROBOT_control大概长这样:
MYROBOT: # controls the rear two tires based on individual motors # Publish all joint states ----------------------------------- joint_state_controller: type: joint_state_controller/JointStateController publish_rate: 50 # Controllers ----------------------------------- SOME_JOINT_controller: type: velocity_controllers/JointVelocityController joint: SOME_JOINT pid: {p: 100.0, i: 0.01, d: 10.0} ANOTHER_JOINT_controller: type: effort_controllers/JointPositionController joint: ANOTHER_JOINT pid: {p: 100.0, i: 0.01, d: 10.0}
这里要注意controller的type,要和transimission中的hardwareInterface类型相对应。
在launch文件中添加controller节点启动语句
这里主要是为了加载.yaml文件,以及启动controller的spawn节点,网上的帖子大部分是另外写了一个launch文件,我是直接写在之前我们启动机器人的launch文件中了,也是可以的:
<!-- Load joint controller configurations from YAML file to parameter server --> <rosparam file="$(find MYROBOT_control)/config/MYROBOT_control.yaml" command="load"/> <!-- load controllers --> <node name="controller_spawner" pkg="controller_manager" type="spawner" respawn="false" output="screen" ns="/MYROBOT" args="joint_state_controller SOME_JOINT_controller ANOTHER_JOINT_controller"/>
注意SOME_JOINT_controller等对应着MYROBOT_control.yaml里的SOME_JOINT_controller等名字。
至此,所有的文件和内容都准备好了,通过roslaunch启动以上launch文件,就可以看到小车出现在gazebo的世界中了,这时候通过rostopic list可以看到以下topics,比原来多了关于controller的topics
/clock /gazebo/link_states /gazebo/model_states /gazebo/parameter_descriptions /gazebo/parameter_updates /gazebo/set_link_state /gazebo/set_model_state /gazebo_gui/parameter_descriptions /gazebo_gui/parameter_updates /rosout /rosout_agg /MYROBOT/joint_states /MYROBOT/SOME_JOINT_controller/command /MYROBOT/ANOTHER_JOINT_controller/command
通过rostopic pub向controller发送指令
rostopic pub -r 10 /MYROBOT/SOME_JOINT_controller/command std_msgs/Float64 "data: 100.0"
因为我这边是用的一辆小车,joint是小车的轮子,这时候发现小车并没有动,或只是动了一下,但其实在Gazebo中选定那个轮子发现他其实是在转动的,所以就是说它在空转…这是因为在urdf文件中没有添加轮子的摩擦力标签,其默认是1。所以需要在urdf中添加以下标签,告诉Gazebo轮子的摩擦系数。由此可以看出,Gazebo作为一个物理仿真软件,一切都是物理定理驱动的。
<gazebo reference="rear_right_wheel_link"> <mu1>10000000</mu1> <mu2>10000000</mu2> <kp>10000000</kp> <kd>1</kd> </gazebo> <gazebo reference="rear_left_wheel_link"> <mu1>10000000</mu1> <mu2>10000000</mu2> <kp>10000000</kp> <kd>1</kd> </gazebo>
其中mu1和mu2表示其摩擦系数,kp和kd表示其刚性,具体参见关于<gazebo>标签的说明。
重新启动,在pub一下就可以看到小车疯狂转圈了~但是由于4个轮子还没有协同控制,小车跑起来怪怪的。
至此,ros已经和gazebo连起来了,我们也可以用ros给gazebo里面的机器人发布命令了,散花。