Gravity Compensation
We implemented a gravity compensation algorithm on cartesian controllers. Gravity compenstation is important when the robot needs to work in different orientations.
This example shows how to calculate the parameters and how to configure the contollers.
1. Prequisites
Make sure you have a F/T sensor mounted on the robot flange, and publish its raw data on
cartesian_compliance_controller/ft_sensor_wrenchtopic.Check topic
cartesian_compliance_controller/current_wrenchto see the transformed wrench data is aligned with robot frame.
Note
The cartesian controller will automatically transform the raw F/T sensor data to the base frame based on the urdf.
For dual-arm, please check their topic names.
Your robot base frame z axis should be aligned with the gravity direction.
2. Recording the gravity pose and wrench
We provide a example script to record the data needed for gravity compensation see cartesian_motion_tools/gravity_pose_record.py.
Note
This script will move the robot to 7 different poses and record the end-effector pose and wrench data. So please make sure these poses are reachable and safe for your robot, you can check it first on simulation.
2.1 Run the recording script
Open a new terminal and source your workspace:
source ~/cmb_ws/install/setup.bash
ros2 run cartesian_motion_tools gravity_pose_record --sim True # if you are using simulation
2.2 Calculate the gravity compensation parameters
ros2 run cartesian_motion_tools gravity_compute
It will generates a file named gravity_result.txt under ~/.gravity_compensation/ directory.
Its content looks like:
force:
[-12.26039,-9.02906,-2.64165,0.52321] # [gravity on z axis reference to world frame, offset x, offset y, offset z]
torque:
[0.04930,-0.08519,-0.10053,0.23747] # [center of mass reference to end-effector, offset x, offset y, offset z]
Note
You can find this algorithm on this paper: D. Chen, Y. Zhang, W. He, A. E. Petrilli Barcel´o, J. V. Salazar Luces, and Y. Hirata, “Simplified offset and gravity compensation for wrist-mounted force/torque sensor with a garment manipulation application,” in 2025 IEEE Int. Conf. on Robot. and Biomimetics (ROBIO), 2025
3. Configure the cartesian controller
Reference the example controller configuration file: cartesian_motion_sim/cartesian_sim_bringup/config/cartesian_gazebo_controllers_sa.yaml
Make changes to your robot controller configuration file:
cartesian_compliance_controller:
ros__parameters:
ik_solver: "forward_dynamics"
end_effector_link: "tool0"
robot_base_link: "robot_base_link"
ft_sensor_ref_link: "tool0"
compliance_ref_link: "tool0"
force_enable: false # Make sure you got the correct F/T sensor data
gravity_compensation: false # Set to true to enable gravity compensation
# Copy your results here
force: [-12.26039,-9.02906,-2.64165,0.52321]
torque: [0.04930,-0.08519,-0.10053,0.23747]
force_state_pub: false # Set to true when use the real robot
emergency_stop_threshold: 200.0
joints:
- shoulder_pan_joint
- shoulder_lift_joint
- elbow_joint
- wrist_1_joint
- wrist_2_joint
- wrist_3_joint
# Choose: position or velocity.
command_interfaces:
- position
#- velocity
stiffness: # w.r.t. compliance_ref_link
trans_x: 500.0
trans_y: 500.0
trans_z: 500.0
rot_x: 100.0
rot_y: 100.0
rot_z: 100.0
damping:
trans_x: 1.0
trans_y: 1.0
trans_z: 1.0
rot_x: 0.0
rot_y: 0.0
rot_z: 0.0
solver:
forward_dynamics:
link_mass: 100.0
error_scale: 0.5
iterations: 1
publish_state_feedback: true
pd_gains:
trans_x: {p: 0.1, d: 0.005}
trans_y: {p: 0.1, d: 0.005}
trans_z: {p: 0.1, d: 0.005}
rot_x: {p: 0.5, d: 0.0001}
rot_y: {p: 0.5, d: 0.0001}
rot_z: {p: 0.5, d: 0.0001}
Caution
- For recording:
When using the real robot, first set
force_enableto false,gravity_compensationto false, andforce_state_pubto true.- After computed the gravity compensation:
Set
gravity_compensationto true to enable it, check the topic/cartesian_compliance_controller/current_wrenchto see if it is working. When using the real robot, setforce_enableto true to enable the F/T sensor, andforce_state_pubto true.
Note
- For dual-arm robot:
Please reference the example scripts, then recording the dual-arm pose and wrench to calculate their gravity compensation parameters respectively.
4. Application: Dragging the robot by hand
After the gravity compensation is enabled, you can easily drag the robot even rotating arbitrarily. For realizing this function, we just need set the target pose as same as the current pose in a loop, due to the compliance controller, the robot has a passive compliance behavior.
// Some other tasks ...
// Trigger the dragging task by service flag
task_pushback(TaskPtr("Wait for Service Trigger", [this](){
if(service_flag_){
RCLCPP_INFO(this->get_logger(), "Service triggered, proceeding to next task.");
set_task_finished();
}
}));
// Dragging the robot by hand
task_pushback(TaskPtr("Drag by hand", [this](){
geometry_msgs::msg::PoseStamped current_pose = get_current_pose("ur");
// Create pose map
PoseMap pose_map;
pose_map["ur"] = current_pose;
set_target_pose(pose_map);
if(!service_flag_){
// Keep this task until the service flag is false
set_task_finished();
}
}));