Gazebo | Ignition | Community
Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

Best practice for robot control

I would like to design some control algorithm for a mobile robot in ROS and simulate it with Gazebo.

The goal is to develop such structure of the project to be able to switch the control mechanism from simulation to the real robot. So far I have following project structure:

   ├ urdf
   | └ robot.urdf.xacro
   └ meshes
     └ robot_mesh.dae

   ├ launch
   | └ robot_world.launch
   ├ plugins
   | └ some_world_plugin
   |   └
   └ worlds

   ├ config
   | └ robot_control.yaml
   └ launch
     └ robot_control.launch

   ├ resource
   | └ gui_controller.ui
   ├ scripts
   | └
   └ src
     └ gui_teleop_plugin

I omit CMakeLists.txtx and package.xml files in every package in the above listing for simplicity.

The robot_description package contains .urdf model of the robot with all the links and joints defined. The .urdf file also includes a gazebo plugin to handle the <transmission> tags in the urdf model and load appropriate control manager.

The robot_gazebo package contains .world file with the simulation environment defined, a launch file that launches the world, spawns the robot from robot_description package and runs the controller from the robot_control package. It also contains a gazebo world plugin that is loaded in the .world file and publishes some messages to a custom ROS topic /robot/is_in_area (std_msgs::Bool carrying information about the position of the robot - is the robot at some specified position? True or False).

The robot_control package contains the definitions of the joint controllers, its pid and a .launch file that creates a topics for joints state and control commands: /robot/joint_state, /robot/joint1_controller/command etc.

The robot_teleop package contains a QT plugin to rqt. The GUI structure (widget) is defined in the gui_controller.ui file. The Plugin, signals and connections between buttons and functions are defined in the file. The push of the button calls a function which publishes into the /robot/joint1_controller/command topic. And the script for running the plugin is written in the file.

This way I have a robot in my gazebo world simulation that can be controlled via GUI buttons on the screen and a topic that gets an information about whether the robot is at specific area or out of that area ( This way it works and makes sense to me. If there is a best practice that contradict my structure, please, tell me.

Now I want to make an automatic controller that would move the robot and make decisions based on the state of the world/robot. I was thinking I would create a new package robot_auto or such, that would contain a gazebo model plugin. The model plugin would move the robot by publishing into the /robot/joint1_controller/command topic, just as the GUI does. And that I would read the /robot/is_in_area and change the robot direction when the robot is out of the area. The desired behavior is kind of bouncing off the area borders.

Now I'm not sure if that is the best idea. After all I wand the automatic control to be plug-able into the real world robot without Gazebo. What is the best practice for such goal?