Skip to content

Commit 7fa7f9c

Browse files
committed
Backport (#39), but without moveit servo (incompatible)
--------- (cherry picked from commit 418f04c)
1 parent 5ccc08b commit 7fa7f9c

18 files changed

+558
-44
lines changed

README.md

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,42 @@ Set of cartesian controllers for ros2_control
55
***The current devs are based on the jazzy ROS 2 distribution (Ubuntu 24.04 LTS)***
66

77
[![CI](https://github.com/ICube-Robotics/cartesian_controllers_ros2/actions/workflows/ci.yml/badge.svg)](https://github.com/ICube-Robotics/cartesian_controllers_ros2/actions/workflows/ci.yml)
8+
9+
10+
11+
### Installation of the package
12+
13+
```bash
14+
# Create a ros2 workspace with a source dir inside
15+
mkdir -p ws_cartesian_controllers/src
16+
17+
# GOTO source dir
18+
cd ws_cartesian_controllers/src
19+
20+
# clone this repos
21+
git clone https://github.com/ICube-Robotics/cartesian_controllers_ros2.git
22+
23+
# Use VCS to clone (and checkout the correct branches) the repositories of the deps
24+
vcs import . < cartesian_controllers_ros2/cartesian_controllers_ros2.repos
25+
26+
# GOTO source dir
27+
cd ..
28+
29+
# Source ROS2 distro
30+
source /opt/ros/jazzy/setup.bash
31+
32+
# Install the dependencies of ALL packages
33+
# sudo rosdep init && rosdep update
34+
rosdep install --ignore-src --from-paths . -y -r
35+
36+
# Build
37+
colcon build --cmake-args -DCMAKE_BUILD_TYPE=Release --symlink-install
38+
39+
# Source this workspace
40+
source install/setup.bash
41+
```
42+
43+
44+
### Examples
45+
46+
See the repos [ICube-Robotics/cartesian_controllers_ros2_examples](https://github.com/ICube-Robotics/cartesian_controllers_ros2_examples).

cartesian_control_msgs/msg/VicControllerState.msg

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ float64[] joint_command_position # optional
2828
float64[] joint_command_velocity # optional
2929
float64[] joint_command_acceleration # optional
3030
float64[] joint_command_effort # optional
31+
float64[] twist_command # optional
3132

3233
# Misc.
3334
std_msgs/Float64MultiArray natural_inertia # optional

cartesian_vic_controller/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ add_library(cartesian_vic_rules SHARED
7070
# Vanilla VIC rules (basic admittance / impedance control laws)
7171
src/rules/vanilla_cartesian_admittance_rule.cpp
7272
src/rules/vanilla_cartesian_impedance_rule.cpp
73+
src/rules/twist_cmd_cartesian_admittance_rule.cpp
7374
)
7475
target_compile_features(cartesian_vic_rules PUBLIC cxx_std_17)
7576
target_include_directories(cartesian_vic_rules PUBLIC

cartesian_vic_controller/README.md

Lines changed: 96 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,53 @@
11
# cartesian_vic_controller
22

3-
This is a cartesian VIC controller based on the package `admittance_controller` from [ros-controls/ros2_controllers](https://github.com/ros-controls/ros2_controllers/tree/master).
3+
This is a cartesian VIC controller inspired by the package `admittance_controller` from [ros-controls/ros2_controllers](https://github.com/ros-controls/ros2_controllers/tree/master).
44

55
> **Warning**
66
>
77
> This package is currently under development and possibly unsafe if used to control an actual robot!
8+
> For instance, a singularity avoidance strategy has still to be implemented in the default VIC.
89
910
## Control law
1011

12+
Let us consider a $n-DoF$ serial manipulator robot whose dynamics can be modeled as
13+
14+
$$
15+
\begin{align}
16+
H(q) \ddot{q} + C(\dot{q}, q) + G(q) = \tau_c + J(q) f_{ext}
17+
\end{align}
18+
$$
19+
20+
where $H(q) \in \mathbb{R}^{n \times n}$ is the joint space inertia matrix, $C(\dot{q}, q) \in \mathbb{R}^{n}$ contains the coriolis and centrifugal terms, $G(q) \in \mathbb{R}^{n}$ represents the gravity terms, and $f_{ext}$ is the external wrench.
21+
22+
> [!NOTE]
23+
> In the code as well as in the following, we define $J(q)$ as the "geometrical" Jacobian matrix, not the analytical one usually used in papers and textbooks.
24+
> The reason is that we do not need/want to choose an angle parameterization (i.e., Euler, Yaw-Pitch-Roll, Quaternions, etc.) if not strictly required by the application.
25+
> The orientation is provided to the controller in the form of a rotation matrix and we use angle-axis representation to compute orientation errors in the VIC rules.
26+
> However, note that other rule implementations (e.g., QP, NMPC, etc.) will require an appropriate parameterization of the robot orientation and make the use of the geometrical Jacobian incorrect...
27+
> For instance, see [this document](https://www.diag.uniroma1.it/deluca/rob2_en/15_ImpedanceControl.pdf) for reference.
28+
1129
The controller imposes the following cartesian behavior
1230

1331
$$
1432
\begin{align}
15-
M \ddot{e} + D \dot{e} + K e = - f_{ext}
33+
M \ddot{e} + D \dot{e} + K e = f_{ext} - f_{ref}
1634
\end{align}
1735
$$
1836

1937
where $e = p^d - p$, $M$ and $D$ are the (positive definite) desired inertia and damping matrix, respectively, and $K^d$ is the (positive semi-definite) desired stiffness matrix.
38+
The reference force $f_{ref}$ is the force that the robot will apply in the absence of interference with the K and D terms (i.e., if $K \tilde 0$, then $f_{ext} \tilde f_{ref}$ in permanent regime).
2039

2140
The cartesian acceleration command $\ddot{p}^c$ is therefore computed as
2241

2342
$$
2443
\begin{align}
25-
\ddot{p}^c = \ddot{p}^d + M^{-1} \left( D \dot{e} + K \dot{e} + f_{ext} \right)
44+
\ddot{p}^c = \ddot{p}^d + M^{-1} \left( D \dot{e} + K \dot{e} - f_{ext} + f_{ref} \right)
2645
\end{align}
2746
$$
2847

29-
and integrated to obtain the cartesian velocity command $\dot{p}^c$.
48+
### 1) Admittance control mode
49+
50+
The cartesian acceleration is integrated to obtain the cartesian velocity command $\dot{p}^c$.
3051

3152
The joint velocity command $\dot{q}^c$ is computed from $\dot{p}^c$ using the `kinematics_interface`.
3253

@@ -40,13 +61,49 @@ $$
4061

4162
where $q$ is the **measured** joint position and $T_s$ is the controller sampling time.
4263

64+
See [vanilla_cartesian_admittance_rule](src/rules/vanilla_cartesian_admittance_rule.cpp) for implementation details.
65+
66+
### 2) Impedance control mode
67+
68+
The joint acceleration command is first computed as
69+
70+
$$
71+
\begin{align}
72+
\ddot{q}^c = J^{\dagger} \left( \ddot{p}^c - \dot{J}(q) \dot{q} \right)
73+
\end{align}
74+
$$
75+
76+
Then, the joint torque control is computed from $\ddot{q}^c$ such that, if the gravity compensation is deactivated,
77+
78+
$$
79+
\begin{align}
80+
\tau^c = H(q) \ddot{q}^c - J(q)^{T} f_{ext}
81+
\end{align}
82+
$$
83+
84+
If the gravity compensation is activated (see `vic.activate_gravity_compensation` parameters), the control law becomes
85+
86+
$$
87+
\begin{align}
88+
\tau^c = H(q) \ddot{q}^c + C(\dot{q}, q) + G(q) - J(q)^{T} f_{ext}
89+
\end{align}
90+
$$
91+
92+
See [vanilla_cartesian_impedance_rule](src/rules/vanilla_cartesian_impedance_rule.cpp) for implementation details.
93+
4394
## Topics
4495

96+
97+
98+
![VIC topics](./doc/VIC_controller_topic_relation.drawio.png)
99+
45100
- `~/compliant_frame_reference` (input topic) [`cartesian_control_msgs::msg::CompliantFrameTrajectory`]
46101

47102
Target (cartesian) compliant frame containing at least a pose, a twist.
48103

49-
Additionally, a desired compliance (stiffness, damping, inertia) can be provided for each reference cartesian state in the trajectory. Otherwise, the ros parameters are used. For instance you could provide the following ros parameters:
104+
Additionally, a desired compliance (stiffness, damping, inertia) can be provided for each reference cartesian state in the trajectory.
105+
Otherwise, the ros parameters are used to retrieve the default values.
106+
For instance you could provide the following default impedance parameters:
50107

51108
```yaml
52109
<controller_name>:
@@ -59,12 +116,10 @@ where $q$ is the **measured** joint position and $T_s$ is the controller samplin
59116
stiffness: [200., 200., 200., 50., 50., 50.]
60117
```
61118
62-
- `~/state` (output topic) [`cartesian_control_msgs::msg::VicControllerState`]
119+
- `~/status` (output topic) [`cartesian_control_msgs::msg::VicControllerState`]
63120

64121
Topic publishing controller internal states.
65122

66-
**TODO(tpoignonec)** Implements + use custom message `VicControllerState`
67-
68123

69124
## ros2_control interfaces
70125

@@ -74,9 +129,39 @@ The state interfaces are defined with ``joints`` and ``state_interfaces`` parame
74129
The necessary state interfaces are ``position`` and ``velocity``.
75130
**Both are mandatory!**
76131

77-
Additionally, the `Force Torque Sensor` semantic component is used and requires force state interfaces.
132+
The `Force Torque Sensor` semantic component is used and requires force state interfaces (optional, depending on rule requirements).
133+
To disable the force-torque sensor, set `ft_sensor.is_enabled` to false.
134+
135+
```yaml
136+
<controller_name>:
137+
...
138+
ft_sensor:
139+
is_enabled: false
140+
name: "" # sensor name in URDF
141+
frame:
142+
id: "" # F/T sensor frame (in which the wrench is expressed)
143+
...
144+
```
145+
146+
Similarly, some rules can use external torque sensor (e.g., useful for nullspace control)
147+
148+
```yaml
149+
<controller_name>:
150+
...
151+
external_torque_sensor:
152+
is_enabled: false # set to true to enable
153+
name: "" # sensor name use by the semantic component
154+
...
155+
```
156+
78157

79158
### Commands
80159

81-
Ideally, the control interface is a joint ``velocity`` group.
82-
The controller can also use a ``position`` command interface.
160+
- Admittance control:
161+
162+
Ideally, the control interface is a joint `velocity` group.
163+
The controller can also use a `position` command interface.
164+
165+
- Impedance control:
166+
167+
`effort` command interface required.

cartesian_vic_controller/cartesian_vic_rules.xml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,11 @@
1313
Classical impedance control law.
1414
</description>
1515
</class>
16+
<class name="cartesian_vic_controller/TwistCmdCartesianAdmittanceRule"
17+
type="cartesian_vic_controller::TwistCmdCartesianAdmittanceRule"
18+
base_class_type="cartesian_vic_controller::CartesianVicRule">
19+
<description>
20+
Classical admittance control law returning a twist command.
21+
</description>
22+
</class>
1623
</library>
Loading

cartesian_vic_controller/include/cartesian_vic_controller/cartesian_vic_rule.hpp

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
#include "pluginlib/class_loader.hpp"
3131

3232
// msgs
33+
#include "geometry_msgs/msg/twist.hpp"
3334
#include "geometry_msgs/msg/wrench_stamped.hpp"
3435
#include "tf2_geometry_msgs/tf2_geometry_msgs.hpp"
3536
#include "trajectory_msgs/msg/joint_trajectory_point.hpp"
@@ -62,7 +63,7 @@ class CartesianVicRule
6263

6364
/// Configure vic rule
6465
virtual controller_interface::return_type configure(
65-
const std::shared_ptr<rclcpp_lifecycle::LifecycleNode> & node,
66+
const std::shared_ptr<rclcpp::node_interfaces::NodeParametersInterface> & parameters_interface,
6667
const size_t num_joint);
6768

6869
/// Soft reset vic rule (set cartesian ref as current pose)
@@ -118,6 +119,7 @@ class CartesianVicRule
118119
* Compute joint command from the current cartesian tracking errors
119120
* and the desired interaction parameters (M, K, D). This function is
120121
* to be used when no external torque sensor is available.
122+
* Not implemented by all plugins!
121123
*
122124
* \param[in] period time in seconds since last controller update
123125
* \param[out] joint_state_command computed joint state command
@@ -127,6 +129,19 @@ class CartesianVicRule
127129
trajectory_msgs::msg::JointTrajectoryPoint & joint_state_command
128130
);
129131

132+
/**
133+
* Compute twist command from the current cartesian tracking errors
134+
* and the desired interaction parameters (M, K, D).
135+
* Not implemented by all plugins!
136+
*
137+
* \param[in] period time in seconds since last controller update
138+
* \param[out] twist_command computed cartesian twist command
139+
*/
140+
controller_interface::return_type compute_controls(
141+
const rclcpp::Duration & period,
142+
geometry_msgs::msg::Twist & twist_command
143+
);
144+
130145
/// Get current control mode (ADMITTANCE / IMPEDANCE / INVALID)
131146
ControlMode get_control_mode() const {return control_mode_;}
132147

cartesian_vic_controller/include/cartesian_vic_controller/cartesian_vic_state.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,7 @@ class VicCommandData
174174
explicit VicCommandData(size_t num_joints)
175175
{
176176
// Allocate and reset command
177+
twist_command.setZero();
177178
joint_command_position = Eigen::VectorXd::Zero(num_joints);
178179
joint_command_velocity = Eigen::VectorXd::Zero(num_joints);
179180
joint_command_acceleration = Eigen::VectorXd::Zero(num_joints);
@@ -193,13 +194,15 @@ class VicCommandData
193194
// Computed command
194195
//------------------------
195196
// Commanded joint state computed from "robot_command_twist"
197+
Eigen::Vector<double, 6> twist_command;
196198
Eigen::VectorXd joint_command_position;
197199
Eigen::VectorXd joint_command_velocity;
198200
Eigen::VectorXd joint_command_acceleration;
199201
Eigen::VectorXd joint_command_effort;
200202

201203
// Command availability
202204
//------------------------
205+
bool has_twist_command = false;
203206
bool has_position_command = false;
204207
bool has_velocity_command = false;
205208
bool has_acceleration_command = false;
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
// Copyright 2024 ICUBE Laboratory, University of Strasbourg
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
//
15+
/// \authors: Thibault Poignonec
16+
/// \description: Plugin for CartesianVicRule implementing "classical" admittance control
17+
18+
#ifndef CARTESIAN_VIC_CONTROLLER__RULES__TWIST_CMD_CARTESIAN_ADMITTANCE_RULE_HPP_
19+
#define CARTESIAN_VIC_CONTROLLER__RULES__TWIST_CMD_CARTESIAN_ADMITTANCE_RULE_HPP_
20+
21+
22+
#include <memory>
23+
24+
#include "cartesian_vic_controller/cartesian_vic_rule.hpp"
25+
26+
namespace cartesian_vic_controller
27+
{
28+
29+
class TwistCmdCartesianAdmittanceRule : public CartesianVicRule
30+
{
31+
public:
32+
controller_interface::return_type init(
33+
const std::shared_ptr<cartesian_vic_controller::ParamListener> & parameter_handler
34+
) override;
35+
36+
/// Configure admittance solver
37+
controller_interface::return_type configure(
38+
const std::shared_ptr<rclcpp::node_interfaces::NodeParametersInterface> & parameters_interface,
39+
const size_t num_joints
40+
) override;
41+
42+
/// Reset all values back to default
43+
controller_interface::return_type reset(const size_t num_joints) override;
44+
45+
protected:
46+
/// Actual vic (admittance) control logic
47+
bool compute_controls(
48+
double dt /*period in seconds*/,
49+
const VicInputData & vic_input_data,
50+
VicCommandData & vic_command_data) override;
51+
52+
bool reset_rule__internal_storage(const size_t num_joints);
53+
};
54+
55+
} // namespace cartesian_vic_controller
56+
57+
#endif // CARTESIAN_VIC_CONTROLLER__RULES__TWIST_CMD_CARTESIAN_ADMITTANCE_RULE_HPP_

cartesian_vic_controller/include/cartesian_vic_controller/rules/vanilla_cartesian_admittance_rule.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ class VanillaCartesianAdmittanceRule : public CartesianVicRule
3535

3636
/// Configure admittance solver
3737
controller_interface::return_type configure(
38-
const std::shared_ptr<rclcpp_lifecycle::LifecycleNode> & node,
38+
const std::shared_ptr<rclcpp::node_interfaces::NodeParametersInterface> & parameters_interface,
3939
const size_t num_joints
4040
) override;
4141

cartesian_vic_controller/include/cartesian_vic_controller/rules/vanilla_cartesian_impedance_rule.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ class VanillaCartesianImpedanceRule : public CartesianVicRule
3535

3636
/// Configure admittance solver
3737
controller_interface::return_type configure(
38-
const std::shared_ptr<rclcpp_lifecycle::LifecycleNode> & node,
38+
const std::shared_ptr<rclcpp::node_interfaces::NodeParametersInterface> & parameters_interface,
3939
const size_t num_joints
4040
) override;
4141

0 commit comments

Comments
 (0)