Homework: Gazebo and ROS Control
Table of Contents
1 Submission Instructions
Just like all other assignments so far, this will be submitted via Classroom for GitHub. See Canvas for the secret link for creating your private repository. Note that unlike other assignments, this assignment's repository will automatically start out with a copy of the rrbot_control_me495 package. You will be adding nodes, launch files, configuration files, and README answers to this package, and pushing your changes to the repo automatically created for you by GitHub Classroom.
All deliverables described below should be pushed to this repository, and a URL similar to https://github.com/ME495-EmbeddedSystems/homework-4-f2018-YOUR-USERNAME should be submitted via Canvas before the due date.
All answers should be in a README file located in the root of the package (a template has been created for you). Items that should specifically be addressed in the README and in the repo are highlighted like this. The README should have nice formatting, your repo should have evidence of proper Git usage (multiple commits, no extra files, etc.), and you should properly conform to the file hierarchy pre-specified by the package. If you have questions about anything, please post to Canvas.
2 rrbot
and ROS interfacing
First you should complete the Using a URDF in Gazebo Tutorial and the Using Gazebo plugins with ROS Tutorial. It is up to you how carefully you follow the tutorials, but many hints and further explanations related to the tasks below are included in the tutorials. You will be writing new configuration files, launch files, and nodes that will be added to your copy of the rrbot_control_me495
package cloned from GitHub Classroom. These files will add new functionality to the gazebo_ros_demos demos package discussed in these two tutorials. Note, for both of the tutorials the kinetic-devel
branch of gazebo_ros_demos
should work fine on Melodic.
- In this problem, your first goal is to use the Gazebo GUI to create a
custom world. This world should have at least three built-in models
(dumpsters, cones, houses, etc.). Later you will be inserting an
rrbot
model into this world. Save this world file and add it to your repository; be sure your README links to this world file. - Write a launch file that starts Gazebo with your custom world from the
previous problem, and inserts the default
rrbot
model fromgazebo_ros_demos
. You should use thespawn_model
node fromgazebo_ros
to insert therrbot
model into the world. README should link to the launch file and include a screenshot of the rrbot in the custom world. - Once Gazebo is running with your simulated
rrbot
you will use theimage_view
orrqt_image_view
node to display the simulated camera feed from Gazebo. README should include a screenshot of image and should address the following: (a) what command was used to start your image viewer? (b) what is the name of the plugin responsible for simulating the camera? (c) what topic is the simulated image published on and where was this topic name defined? Write a launch file that starts
rviz
with a nice configuration to view the camera, the laser scanner, and therrbot
. For now, your launch file should also include thejoint_state_publisher
to specify the joint values for ROS (we'll discuss why this is necessary in the next section). You can use the rrbot_rviz.launch file for inspiration. If you can't get the laser scans to show up inrviz
, you may be running into a driver issue. By default, therrbot
uses the gazebo_ros_gpu_laser plugin to simulate the laser scanner. This plugin is supposed to work by using your graphics card to compute the ray-tracing required to simulate the laser scanner, but in my experience, this doesn't work very well for many graphics card/driver combos. If the laser scanner isn't showing up, try one of the following:- Modify the appropriate xacro files to use a non-GPU laser scanner. The plugin is called gazebo_ros_laser.
- Set the LIBGL_ALWAYS_SOFTWARE environment variable to ensure that your
system uses the CPU instead of your GPU for rendering calculations.
Note that this may have a serious impact on the performance of your
system. It is not recommended to put this in your
.bashrc
. The command to set this environment variable isexport LIBGL_ALWAYS_SOFTWARE=1
.
Modify the noise settings for the simulated laser scanner and inspect how the scans change. Your README should include a link to the launch file, a link to your rviz configuration, screenshots of the simulated laser scanner in rviz with both noise settings, and a description of which files were edited to change the noise settings. If you ran into issues getting the laser scanner to show up, you should also describe how you fixed it. When you are done with this problem feel free to either revert or keep any edits you made regarding the noise models in the laser plugin in the
gazebo_ros_demos
package; for the next section it doesn't matter what the settings are.
3 ROS control, ROS communication, and custom plugins
Before completing this section, you should complete the following tutorials:
As before, it is up to you to decide how closely you want to follow the tutorials, but they do provide quite a lot of helpful information.
In the last section, we needed the
joint_state_publisher
to createsensor_msgs/JointState
information to tellrviz
the pose of therrbot
. This is an artifact of the way thegazebo_ros_control
package's plugins interact with Gazebo/ROS. By default, thegazebo_ros_control
plugin does not provide joint state information to ROS. Rather, you must load a properly-configured joint_state_controller plugin with thespawner
node from thecontroller_manager
package. This plugin then interacts with the Gazebo simulation and automatically publishes joint state information. One could easily write a custom plugin to provide a less-complicated interface between ROS and Gazebo, but it would likely be less generic and not feature the same hardware abstractions thatros_control
provides.Complete the following tasks:
- Write a YAML file that configures the
joint_state_controller/JointStateController
to convert model poses tojoint_states
information. - Write a launch file that starts
rviz
, aspawner
node, therobot_state_publisher
, and loads the correctrobot_description
parameter. This can either be a new launch file, or you can modify one of your launch files from the previous section and add an argument to toggle between thejoint_state_publisher
providing joint state information and Gazebo providing the joint state information. You may need toremap
or relay the joint state information to get the correct topic names. Just like in the tutorials, I'd recommend one launch file for starting Gazebo with your custom world, and a separate launch file for starting everything else.
Your README should include a link to the joint state controller configuration file, a link to the launch file, and instructions for running the launch file(s).
- Write a YAML file that configures the
- Write a ROS node in Python that uses the
/gazebo/apply_joint_effort
service to apply torques to therrbot
joints to get it to swing back in forth. If you are really fancy, you could even write a controller that subscribes to the joint state information and stabilizes therrbot
to a reference configuration trajectory by setting the joint torques (this is not necessary!). Add a link to the node source code to your README, and describe how to run your node (could be one launch file, two launch files, or two launch files and a rosun command). The template package you cloned includes a custom ROS plugin. This plugin subscribes to a custom message that is specifically used for setting the joint configurations of the
rrbot
. The structure of the plugin is very similar to that of a plugin you might find in the gazebo_ros_pkgs package, but all code has been merged into a single file to make it a bit easier to follow. In what follows, we will give a high-level overview of the plugin. You are welcome to study the code and ask if you have any questions, but the exact functionality of this code is not the primary purpose of this problem.The plugin has two threads:
- The
RRBotPosControl::OnUpdate
function is set to be a callback to Gazebo's simulation update loop; this is done with boost::bind. So the first thread idles until Gazebo takes a simulation step, and then theRRBotPosControl::OnUpdate
function is called. This function simply sets the joint velocities and torques for bothrrbot
joints to be zero, and sets the joint angles to be the values specified by the private member variablerefAngles
. - For the second thread we call the
RRBotPosControl::QueueThread
function repeatedly in a loop with 0.01 second delays between calls. Each time we call this function, the function checks to see if there is a callback in our private member variablesubQueue
which is of typeros::CallbackQueue
. If there is a callback available, we handle it. This is really just a custom version ofros::spin()
. We create a ROS subscriber that uses thesubQueue
variable for it'sros::CallbackQueue
, and we set it to callRRBotPosControl::jointConfigCB()
every time there is a new message on this topic. So every time a new message is published on therrbot_joint_position_control/rrbot_ref_joint_config
topic, the value of the latest message and thejointConfigCB
are put at the top of the callback queue. The next time theRRBotPosControl::QueueThread
function checks to see if there is something in the callback queue, it will see there is something there, and it will calljointConfigCB
with the latest copy of the message as the argument. Then all thejointConfigCB
function does is set the values of therefAngles
variable; which is the variable used by the other thread to specify the joint angles of therrbot
.
The first step is to make sure you compile this plugin with
catkin_make
. Next you need a version of therrbot
model that will use this custom plugin. Copy the correct files from therrbot_description
package into theurdf/
directory of your package. Then edit these files to set the Gazebo simulation to use the custom plugin, and finally write a new launch file that starts Gazebo with the edited version of therrbot
loaded. Your README should include the following:- A description of the custom message that the plugin subscribes to.
- A link to the launch file that starts Gazebo with the custom plugin.
- A description of what you had to modify in the
rrbot_description
files to get it to load your custom plugin. This should include the name of the plugin, and how you found this name (hint: look in theCMakeLists.txt
).
- The
- Write a ROS node in Python that publishes the custom message on the correct
topic to get the
rrbot
to follow a cyclic trajectory (hint: your node that provided/joint_states
information from homework 2 should need very little editing). When you add this node to your launch file from the previous section you should be able to, from a single launch file, start Gazebo with your modifiedrrbot
in your custom world, and have a ROS node that is sending commands to move the simulation in a cyclic trajectory. Your README should include a link to the updated final launch file, instructions for launching, and a link to the node that was written to control the rrbot simulation.