ROS_Control
In general, there are several types of control software. Some of them are available out of the box whereas some others are those you may write by yourselves. ros_control is among the out-of-the-box control software you can directly use (so that you don’t need to write one from scratch) which is compatible with third-party packages built on top of ROS (such as ros_navigation and MoveIt). Hence, ros_control offers at least two advantages:
- out-of-the-box solution
- compatibility for third-party ROS packages
Historically, ros_control started from pr2_controller_manager developed by Willow Garage specifically for PR2 robot only. In late 2012, Willow Garage and hiDOF started developing ros_control as a robot-agnostic control software. The development of ros_control was later done by PAL Robotics and the community.
A presentation about ros_control can be found here: video and slides.
ros_control has several main components:
- ros_controllers: consisting of several types of controllers one can use.
- controller_manager: managing all the controllers
- hardware_interface: providing a standard interface between controller(s) and the robot hardware through the hardware interface node.
Besides the aforementioned components, the following components also exist in ros_control:
- transmissions_interface: supports several transmission methods such as reducer, differential, and fourbar linkage.
- joint_limits_interface: defining joint limits.
If one would like to use ros_control with a real robot, he/she should provide the following customized components:
- hardware interface node (this is a piece of code/software customized to someone’s robot).
- a real robot (with actuators/motors and sensors).
Now let’s talk about some details of the ros_control main components. The following is the wiki page of ros_control: http://wiki.ros.org/ros_control
There are several types of controllers available in ros_control:
>position_controllers:
- joint_position_controller: sets one joint position at once.
- joint_group_position_controller: sets multiple joint positions at once.
>velocity_controllers:
- joint_velocity_controller: sets one joint velocity at once.
- joint_group_velocity_controller: sets multiple joint velocities at once.
>effort_controllers: commands the desired force/torque to joints.
- joint_effort_controller
- joint_position_controller
- joint_velocity_controller
>joint_trajectory_controller: is used to control a trajectory-following motion. It has spline interpolation capability.
- position_controller
- velocity_controller
- effort_controller
- position_velocity_controller
- position_velocity_acceleration_controller
>diff_drive_controller: is used to control differential-drive mobile robot.
>ackermann_steering_controller: is used to control ackermann-steering mobile robot.
>forward_command_controller
>gripper_action_controller
There are also read-only controllers (hence they actually just perform sensor state reporting; they are actually not controllers):
>joint_state_controller: publishes the joint state as “sensor_msgs/JointState” data type.
>force_torque_sensor_controller: publishes force/torque sensor reading as “geometry_msgs/Wrench” data type.
>imu_sensor_controller: publishes IMU state as “sensor_msgs/Imu” data type.
It has capability to manage the controllers such as list, load, unload, start, stop, spawn, switch, kill. You can run the controller_manager in several ways:
- CLI commands
- running the controller_manager by using a launch file
- graphically running the controller_manager by using RQT Plugin
The following two hardware interfaces are the most commonly used:
- Joint Command Interface
- Joint State Interface
Beside these two hardware interfaces, there are also some other hardware interfaces available in ros_control:
- Actuator State Interface
- Actuator Command Interface
- PosVelJointInterface
- PosVelAccJointInterface
- Force-torque Sensor Interface
- IMU Sensor Interface
4 transmissions
Transmissions can be conveniently specified in URDF such as the following:
1 2 3 4 5 6 7 8 9 10 |
<transmission name="my_transmission"> <type>transmission_interface/SimpleTransmission</type> <joint name="foo_joint"> <hardwareInterface>EffortJointInterface</hardwareInterface> </joint> <actuator name="foo_motor"> <mechanicalReduction>50</mechanicalReduction> <hardwareInterface>EffortJointInterface</hardwareInterface> </actuator> </transmission> |
The joint limits can be specified by using either URDF or YAML file.
Specifying joint limits in URDF looks like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
<joint name="$foo_joint" type="revolute"> <!-- other joint description elements --> <!-- Joint limits --> <limit lower="0.0" upper="1.0" effort="10.0" velocity="5.0" /> <!-- Soft limits --> <safety_controller k_position="100" k_velocity="10" soft_lower_limit="0.1" soft_upper_limit="0.9" /> </joint> |
Specifying joint limits in a YAML file looks like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
joint_limits: joint1: has_position_limits: true min_position: 0.0 max_position: 1.0 has_velocity_limits: true max_velocity: 2.0 has_acceleration_limits: true max_acceleration: 5.0 has_jerk_limits: true max_jerk: 100.0 has_effort_limits: true max_effort: 5.0 joint2: has_position_limits: false # Continuous joint has_velocity_limits: true max_velocity: 4.0 |
IMPORTANT
Notice that a joint can use more than one controller, BUT NOT AT THE SAME TIME.
Other useful links: