实操 | Making my own Autonomous Robot in ROS / Gazebo, Day 2: Enable the robot
Day 2: Enable the robot
The goal of this post is to make the robot drivable.
Platform
- Ubuntu 14.04
- ROS indigo
Source
Sources for this tutorial can be found on GitHub
Prepare the repo
git checkout master
git branch day2_enable_robot
git push --set-upstream origin day2_enable_robot
Now in a new branch we start working on enabling the robot.
Connect your robot to ROS
Alright, our robot is all nice and has this new car smell, but we can’t do anything with it yet as it has no connection with ROS. In order to add this connection we need to add gazebeo plugins to our model. There are different kinds of plugins:
- World: Dynamic changes to the world, e.g. Physics, like illumination or gravity, inserting models
- Model: Manipulation of models (robots), e.g. move the robots
- Sensor: Feedback from virtual sensor, like camera, laser scanner
- System: Plugins that are loaded by the GUI, like saving images
First of all we’ll use a plugin to provide access to the joints of the wheels. The transmission tags in our URDF will be used by this plugin the define how to link the joints to controllers. To activate the plugin, add the following to mybot.gazebo:
<gazebo> <plugin name="gazebo_ros_control" filename="libgazebo_ros_control.so"> <robotNamespace>/mybot</robotNamespace> </plugin> </gazebo>
Look at this tutorial for more information on how this plugin works.
With this plugin, we will be able to control the joints, however we need to provide some extra configuration and explicitely start controllers for the joints. In order to do so, we’ll use the package mybot_control that we have defined before. Let’s first create the configuration file:
roscd mybot_control mkdir config cd config gedit mybot_control.yaml
This file will define three controllers: one for each wheel, connections to the joint by the transmission tag, one for publishing the joint states. It also defined the PID gains to use for this controller:
mybot: # Publish all joint states ----------------------------------- joint_state_controller: type: joint_state_controller/JointStateController publish_rate: 50 # Effort Controllers --------------------------------------- leftWheel_effort_controller: type: effort_controllers/JointEffortController joint: left_wheel_hinge pid: {p: 100.0, i: 0.1, d: 10.0} rightWheel_effort_controller: type: effort_controllers/JointEffortController joint: right_wheel_hinge pid: {p: 100.0, i: 0.1, d: 10.0}
Now we need to create a launch file to start the controllers. For this let’s do:
roscd mybot_control mkdir launch cd launch gedit mybot_control.launch
In this file we’ll put two things. First we’ll load the configuration and the controllers, and we’ll also start a node that will provide 3D transforms (tf) of our robot. This is not mandatory but that makes the simulation more complete:
<launch> <!-- Load joint controller configurations from YAML file to parameter server --> <rosparam file="$(find mybot_control)/config/mybot_control.yaml" command="load"/> <!-- load the controllers --> <node name="controller_spawner" pkg="controller_manager" type="spawner" respawn="false" output="screen" ns="/mybot" args="joint_state_controller rightWheel_effort_controller leftWheel_effort_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"> <param name="robot_description" command="$(find xacro)/xacro.py '$(find mybot_description)/urdf/mybot.xacro'" /> <remap from="/joint_states" to="/mybot/joint_states" /> </node> </launch>
We could launch our model on gazebo and then launch the controller, but to save some time (and terminals), we’ll start the controllers automatically by adding a line to the “mybot_world.launch” in the mybot_gazebo package :
<!-- ros_control mybot launch file --> <include file="$(find mybot_control)/launch/mybot_control.launch" />
Now launch your simulations. In a separate terminal, if you do a “rostopic list” you should see the topics corresponding to your controllers. You can send commands manually to your robot:
rostopic pub -1 /mybot/leftWheel_effort_controller/command std_msgs/Float64 "data: 1.5" rostopic pub -1 /mybot/rightWheel_effort_controller/command std_msgs/Float64 "data: 1.0"
The robot should start moving. Congratulations, you can now control your joints through ROS ! You can also monitor the joint states by doing :
rostopic echo /mybot/joint_states
Issue 1
Failed to load plugin libgazebo_ros_control.so
the installation of this packages cleared out all errors for me (tested under indigo) :
- ros-indigo-youbot-gazebo-robot
- ros-indigo-youbot-gazebo-control
- ros-indigo-youbot-description
- ros-indigo-youbot-driver
- ros-indigo-youbot-driver-ros-interface
- ros-indigo-youbot-gazebo-worlds
- ros-indigo-youbot-simulation
- ros-indigo-gazebo-ros-control
- ros-indigo-effort-controllers
- ros-indigo-joint-state-controller
- ros-indigo-joint-trajectory-controller
copy/paste command:
sudo apt-get install ros-indigo-youbot-gazebo-robot ros-indigo-youbot-gazebo-control ros-indigo-youbot-description ros-indigo-youbot-driver ros-indigo-youbot-driver-ros-interface ros-indigo-youbot-gazebo-worlds ros-indigo-youbot-simulation ros-indigo-gazebo-ros-control ros-indigo-effort-controllers ros-indigo-joint-state-controller ros-indigo-joint-trajectory-controller
Issue 2
No valid hardware interface element found in joint
In macro.xacro:
modify
<transmission name="${lr}_trans"> <type>transmission_interface/SimpleTransmission</type> <joint name="${lr}_wheel_hinge"/> <actuator name="${lr}Motor"> <hardwareInterface>EffortJointInterface</hardwareInterface> <mechanicalReduction>10</mechanicalReduction> </actuator> </transmission>
as
<transmission name="${lr}_trans"> <type>transmission_interface/SimpleTransmission</type> <joint name="${lr}_wheel_hinge"> <hardwareInterface>EffortJointInterface</hardwareInterface> </joint> <actuator name="${lr}Motor"> <hardwareInterface>EffortJointInterface</hardwareInterface> <mechanicalReduction>10</mechanicalReduction> </actuator> </transmission>
Teleoperation of your robot
Ok you can control joints individually, but that’s not so convenient when you want to make your mobile robot move around. Let’s use another plugin called differential drive to make it easier. Add this in the gazebo file of your model :
<gazebo> <plugin name="differential_drive_controller" filename="libgazebo_ros_diff_drive.so"> <alwaysOn>true</alwaysOn> <updateRate>100</updateRate> <leftJoint>left_wheel_hinge</leftJoint> <rightJoint>right_wheel_hinge</rightJoint> <wheelSeparation>${chassisWidth+wheelWidth}</wheelSeparation> <wheelDiameter>${2*wheelRadius}</wheelDiameter> <torque>20</torque> <commandTopic>mybot/cmd_vel</commandTopic> <odometryTopic>mybot/odom_diffdrive</odometryTopic> <odometryFrame>odom</odometryFrame> <robotBaseFrame>footprint</robotBaseFrame> </plugin> </gazebo>
This plugin will subscribe to the cmd_vel topic specified with the « commandTopic » tag and convert the messages to the proper commands on the wheels. It also provides some odometry data.
Now, you can start gazebo with the usual launch file.
To teleoperate your robot with the keybord you can use a teleoperation node as provided in turtlesim or turtlebot packages. We just need to remap the topic name to connect it to our robot :
rosrun turtlesim turtle_teleop_key /turtle1/cmd_vel:=/mybot/cmd_vel
rosrun turtlebot_teleop turtlebot_teleop_key /turtlebot_teleop/cmd_vel:=/mybot/cmd_vel
Enjoy the ride !
Issue
package "turtlebot_teleop" is not found
Fix by typing
sudo apt-get install ros-indigo-turtlebot-teleop
References
- [Tutorial] Simulating Sensors in Gazebo (part 2)
- Gazebo Plugin Library
- Gazebo Camera Tutorial