ROS Control
在本教程中,我们将设置模拟控制器来驱动机器人的关节。这将允许我们为MoveIt!这样的规划器提供正确的ROS接口。我们将使用ros_control包,这是ROS中用于控制器接口的新标准。
来源:http://gazebosim.org/tutorials?tut=ros_control&cat=connect_ros
样例代码:https://github.com/ros-simulation/gazebo_ros_demos
ros_control包将机器人执行器的编码器和一个输入设置点的联合状态数据作为输入。它使用一个通用的控制回路反馈机制,典型的PID控制器,来控制输出。ros_control对于没有关节位置、工作等一对一映射的物理机制来说变得更加复杂,但这些场景都是通过传输来考虑的。
使用ros_control和一个简单的Gazebo plugin,可以在Gazebo完成模拟一个机器人的控制器。
在URDF中 添加 transmission elements
要在机器人中使用ros_control,需要在URDF中添加一些额外的元素。<transmission>元素用于将执行机构连接到关节,具体XML格式请参阅<transmission>规范。
对于目前实现中的gazebo_ros_control来说,这些传输标签中重要的信息是:
- name必须对应于URDF中的关节
- transmission的类型, 目前只需要“transmission_interface/SimpleTransmission”。
- 在和标签内,这告诉gazebo_ros_control plugin加载什么硬件接口(position, velocity or effort interfaces)。
添加 gazebo_ros_control plugin
除了transmission 标签之外,还需要在URDF中添加一个Gazebo插件,它可以解析transmission 标签,加载合适的硬件接口和控制器管理器。默认情况下,gazebo_ros_control插件非常简单,不过它也可以通过附加的插件架构进行扩展,允许高级用户在ros_control和Gazebo之间创建他们自己的自定义机器人硬件接口。
默认的XML插件应该添加到你的URDF:
<gazebo>
<plugin name="gazebo_ros_control" filename="libgazebo_ros_control.so">
<robotNamespace>/MYROBOT</robotNamespace>
</plugin>
</gazebo>
gazebo_ros_control 标签也有以下可选子元素:
<robotNamespace>
: 用于此插件实例的ROS名称空间,默认为URDF/SDF中机器人名称<controlPeriod>
: 控制器更新的周期(以秒为单位),默认为Gazebo的周期<robotParam>
: robot_description (URDF)在参数服务器上的位置,默认为’/robot_description’<robotSimType>
: 要使用的自定义机器人sim接口的插件库名称(详见下面),默认为’DefaultRobotHWSim’
默认的gazebo_ros_control行为
默认情况下,如果没有标签,gazebo_ros_control将尝试从URDF中获取与基于ros_control的控制器交互所需的所有信息。这对于大多数情况来说已经足够了,至少对于初学者来说是很好的
默认行为提供以下ros_control接口:
- hardware_interface::JointStateInterface
- hardware_interface::EffortJointInterface
- hardware_interface::VelocityJointInterface - not fully implemented
RRBot Example
我们为在gazebo中想要驱动的每个关节增加了一个块类似于以下。
注意:必须包含在和标签中
打开 ***rrbot.xacro***文件,在底部你应该会看到:
<transmission name="tran1">
<type>transmission_interface/SimpleTransmission</type>
<joint name="joint1">
<hardwareInterface>EffortJointInterface</hardwareInterface>
</joint>
<actuator name="motor1">
<hardwareInterface>EffortJointInterface</hardwareInterface>
<mechanicalReduction>1</mechanicalReduction>
</actuator>
</transmission>
<transmission name="tran2">
<type>transmission_interface/SimpleTransmission</type>
<joint name="joint2">
<hardwareInterface>EffortJointInterface</hardwareInterface>
</joint>
<actuator name="motor2">
<hardwareInterface>EffortJointInterface</hardwareInterface>
<mechanicalReduction>1</mechanicalReduction>
</actuator>
</transmission>
您还将在***rrbot.gazebo***中看到gazebo_ros_control插件, 来读取所有标签:
<gazebo>
<plugin name="gazebo_ros_control" filename="libgazebo_ros_control.so">
<robotNamespace>/rrbot</robotNamespace>
</plugin>
</gazebo>
创建一个ros_controls 包
接下来,我们需要为与Gazebo接口的ros_control控制器创建一个configuration文件和launch文件。
Create new package
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
Create a .yaml config file
PID增益和控制器设置必须保存在一个***yaml***文件中,该文件通过roslaunch文件加载到param服务器。在你的***MYROBOT_control***包的**config文件夹中,将下面的RRBot例子应用到你的机器人上,如MYROBOT_control/config/rrbot_control.yaml:
rrbot:
# Publish all joint states -----------------------------------
joint_state_controller:
type: joint_state_controller/JointStateController
publish_rate: 50
# Position Controllers ---------------------------------------
joint1_position_controller:
type: effort_controllers/JointPositionController
joint: joint1
pid: {p: 100.0, i: 0.01, d: 10.0}
joint2_position_controller:
type: effort_controllers/JointPositionController
joint: joint2
pid: {p: 100.0, i: 0.01, d: 10.0}
Create a roslaunch file
创建一个用于启动ros_control控制器的roslaunch文件。在launch文件夹中创建一个***MYROBOT_control/launch/MYROBOT_control.launch***。启动文件并将下面的RRBot示例应用到您的机器人上:
<launch>
<!-- Load joint controller configurations from YAML file to parameter server -->
<rosparam file="$(find rrbot_control)/config/rrbot_control.yaml" command="load"/>
<!-- load the controllers -->
<node name="controller_spawner" pkg="controller_manager" type="spawner" respawn="false"
output="screen" ns="/rrbot" args="joint1_position_controller joint2_position_controller joint_state_controller"/>
<!-- convert joint states to TF transforms for rviz, etc -->
<node name="robot_state_publisher" pkg="robot_state_publisher" type="robot_state_publisher"
respawn="false" output="screen">
<remap from="/joint_states" to="/rrbot/joint_states" />
</node>
</launch>
Start the controllers using roslaunch
通过运行以下程序测试由ros_control控制的RRBot:
启动RRBot仿真
roslaunch rrbot_gazebo rrbot_world.launch
通过运行第二个启动文件加载两个关节的控制器:
roslaunch rrbot_control rrbot_control.launch
手动发送示例命令
rostopic pub -1 /rrbot/joint1_position_controller/command std_msgs/Float64 "data: 1.5"
rostopic pub -1 /rrbot/joint2_position_controller/command std_msgs/Float64 "data: 1.0"
Use RQT To Send Commands
在本节中,我们将介绍一些工具,以帮助您可视化控制器的性能,并调优控制器可能具有的任何增益/参数,特别是PID增益。我们将使用RQT, ROS的基于插件的用户界面,所以一定要先安装它。
启动RQT
rosrun rqt_gui rqt_gui
在RQT的“Plugins”菜单上添加“Topics->Message Publisher”插件,然后从下拉框中选择主题,可以命令任何你想要发布到的控制器。对于RRBot,添加控制器:
/rrbot/joint1_position_controller/command
然后按右上角的绿色加号按钮。勾选主题名称左侧的复选框,以启用主题发布者。将rate列设置为100(在本例中,我们发送它命令的频率为100hz)。
接下来,展开主题,以便看到“data”行。在expression列中,在数据行中,尝试在joint1的关节极限之间的不同弧度值——在RRBot的情况下,因为关节是连续的,所以没有限制,所以任何值都可以。如果您在本教程中使用RRBot机器人,那么您应该能够让它四处旋转。
接下来,在同一个表达式框中,我们将使用正弦波自动改变值。添加以下
sin(i/100)
对于更先进的控制,你可以配置它发布一个正弦波到你的机器人的确切关节的限制:
sin(i/rate*speed)*diff + offset
- i --表示时间的RQT变量
- rate – 这个表达式被计算的频率。这应该与主题发布者的rate列中的数字相同。推荐值为100。
- speed – 你希望连接启动的速度有多快。开始时只有1,因为速度较慢
- upper_limit lower_limit – 由该控制器控制的硬件的关节极限
- diff – (upper_limit - lower_limit)/2
- offset = upper_limit-diff
可视化控制器的性能
添加一个Plot插件到RQT,并添加相同的topic,你选择了一个以上的主题发布者:
/rrbot/joint1_position_controller/command/data
单击绿色的add按钮。你现在应该看到一个正弦波被绘制在屏幕上。
在Plot插件中添加另一个主题,用于跟踪被控制的执行器的实际位置。您将希望通过调整PID增益来减少这两个值之间的误差,如下一步所示。RRBot:
/rrbot/joint1_position_controller/state/process_value
Tune the PID gains
最后,我们将使用动态重新配置来调整PID控制器的比例、导数和积分增益,假设这适用于你的机器人。
将“Dynamic Reconfigure”插件添加到RQT,然后单击“Expand All”查看子选项。假设你的控制器使用PID,你应该使用一个“PID”选项。点击它应该会显示5个滑块,让你调整控制器,如下面的截图所示。调整这些值,直到获得控制器所需的性能为止。
使用roslaunch保存RQT透视图
可以使用以下命令轻松启动rrbot的预配置RQT透视图:
roslaunch rrbot_control rrbot_rqt.launch
Connect Rviz to Gazebo Simulation
现在您正在模拟使用ros_control向您的机器人发送命令,您还可以使用ros_control的jointstatecontroller从Gazebo读取机器人的状态。一个好的模拟器背后的理念是,您应该能够在真实的硬件上使用与模拟中相同的软件。一个很好的起点是在Rviz中可视化模拟机器人,类似于在真实硬件中实现的方法。
假设您已经启动了上述rosparam和roslaunch文件中的joint_state_controller,那么您的下一步是启动Rviz:
rosrun rviz rviz
在“Global Options”下,将你的“Fixed Frame”更改为“world”,以解决它可能给你的任何错误。
接下来,向Rviz添加一个“RobotModel”显示类型,然后您应该会看到您在Gazebo中的模拟机器人正在Rviz中显示!