diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 27ee719..ae9b904 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -1,9 +1,9 @@
name: CI
on:
push:
- branches: [ main ]
+ branches: [ humble ]
pull_request:
- branches: [ main ]
+ branches: [ humble ]
jobs:
CI:
runs-on: ubuntu-latest
diff --git a/cartesian_vic_controller/CMakeLists.txt b/cartesian_vic_controller/CMakeLists.txt
index a95c4b7..a457193 100644
--- a/cartesian_vic_controller/CMakeLists.txt
+++ b/cartesian_vic_controller/CMakeLists.txt
@@ -49,6 +49,8 @@ add_library(cartesian_vic_controller SHARED
# Vanilla VIC rules (basic admittance / impedance control laws)
src/rules/vanilla_cartesian_admittance_rule.cpp
src/rules/vanilla_cartesian_impedance_rule.cpp
+ # Impedance control for Force Dimension Haptic Interfaces
+ src/rules/fd_impedance_rule.cpp
)
target_compile_features(cartesian_vic_controller PUBLIC cxx_std_17)
target_include_directories(cartesian_vic_controller PUBLIC
diff --git a/cartesian_vic_controller/cartesian_vic_rules.xml b/cartesian_vic_controller/cartesian_vic_rules.xml
index 1147429..325ac63 100644
--- a/cartesian_vic_controller/cartesian_vic_rules.xml
+++ b/cartesian_vic_controller/cartesian_vic_rules.xml
@@ -13,4 +13,11 @@
Classical impedance control law.
+
+
+ Impedance control law for Force Dimension haptic devices (and ONLY those!!!).
+
+
diff --git a/cartesian_vic_controller/config/example_admittance_controller_config.yaml b/cartesian_vic_controller/config/example_admittance_controller_config.yaml
index 945fd18..3b338e4 100644
--- a/cartesian_vic_controller/config/example_admittance_controller_config.yaml
+++ b/cartesian_vic_controller/config/example_admittance_controller_config.yaml
@@ -29,6 +29,7 @@ cartesian_vic_controller:
gravity: [0.0, 0.0, -9.81]
ft_sensor:
+ is_enabled: true
name: ftsensor
frame:
id: ft_sensor # Wrench measurements are in this frame
diff --git a/cartesian_vic_controller/include/cartesian_vic_controller/cartesian_vic_controller.hpp b/cartesian_vic_controller/include/cartesian_vic_controller/cartesian_vic_controller.hpp
index 570a697..e2d161e 100644
--- a/cartesian_vic_controller/include/cartesian_vic_controller/cartesian_vic_controller.hpp
+++ b/cartesian_vic_controller/include/cartesian_vic_controller/cartesian_vic_controller.hpp
@@ -23,6 +23,7 @@
#include
#include "cartesian_vic_controller/visibility_control.h"
+#include "cartesian_vic_controller/measurement_data.hpp"
#include "cartesian_vic_controller/cartesian_vic_rule.hpp"
#include "cartesian_vic_controller/external_torque_sensor.hpp"
@@ -133,16 +134,13 @@ class CartesianVicController : public controller_interface::ControllerInterface
* @brief Read values from hardware interfaces and set corresponding fields of joint_state and
* ft_values
*/
- bool read_state_from_hardware(
- trajectory_msgs::msg::JointTrajectoryPoint & joint_state,
- geometry_msgs::msg::Wrench & ft_values,
- std::vector & external_torques);
+ bool read_state_from_hardware(MeasurementData & measurement_data);
/**
* @brief Initialize the vic rule
*/
- bool initialize_vic_rule(const trajectory_msgs::msg::JointTrajectoryPoint & joint_state);
+ bool initialize_vic_rule(const MeasurementData & measurement_data);
/**
* @brief Try to retrieve the URDF from the parameter server. If this fails, it will
@@ -224,13 +222,18 @@ class CartesianVicController : public controller_interface::ControllerInterface
cartesian_control_msgs::msg::CompliantFrameTrajectory cartesian_state_;
cartesian_control_msgs::msg::CompliantFrameTrajectory cartesian_reference_,
last_cartesian_reference_;
- // joint_state_: current joint readings from the hardware
// joint_command_: joint reference value computed by the controller
- trajectory_msgs::msg::JointTrajectoryPoint joint_state_;
trajectory_msgs::msg::JointTrajectoryPoint joint_command_, last_commanded_joint_state_;
- // ft_values_: values read from the force torque sensor
+
+ // measurement data used by the vic controller
+ // - joint state: current joint readings from the hardware
+ // - measured wrench: values read from the ft sensor (optional)
+ // - external torques: values read from the external torque sensor (optional)
+ MeasurementData measurement_data_{0};
+
+ // ft_values_: values read from the force torque sensor (temporary storage)
geometry_msgs::msg::Wrench ft_values_;
- // ext_torque_values_ : values read from the external torque sensor (optional, zero if disabled)
+ // ext_torque_values_ : values read from the external torque sensor (temporary storage)
std::vector ext_torque_values_;
};
diff --git a/cartesian_vic_controller/include/cartesian_vic_controller/cartesian_vic_rule.hpp b/cartesian_vic_controller/include/cartesian_vic_controller/cartesian_vic_rule.hpp
index 170a6ff..32fd691 100644
--- a/cartesian_vic_controller/include/cartesian_vic_controller/cartesian_vic_rule.hpp
+++ b/cartesian_vic_controller/include/cartesian_vic_controller/cartesian_vic_rule.hpp
@@ -43,6 +43,7 @@
#include "cartesian_vic_controller_parameters.hpp"
// include data structures
+#include "cartesian_vic_controller/measurement_data.hpp"
#include "cartesian_vic_controller/cartesian_vic_state.hpp"
#include "cartesian_vic_controller/compliance_frame_trajectory.hpp"
@@ -84,51 +85,55 @@ class CartesianVicRule
* Compute joint command from the current cartesian tracking errors
* and the desired interaction parameters (M, K, D). This function is
* to be used when no external torque sensor is available.
+ * Internally calls update_input_data() and then compute_controls().
+ *
+ * Note: call only ONE of the update functions.
*
* \param[in] period time in seconds since last controller update
- * \param[in] current_joint_state current joint state of the robot
- * \param[in] measured_wrench most recent measured wrench from force torque sensor
+ * \param[in] measurement_data most recent measurement data, including at
+ * least the joint position and velocity
* \param[out] joint_state_command computed joint state command
*/
controller_interface::return_type update(
const rclcpp::Duration & period,
- const trajectory_msgs::msg::JointTrajectoryPoint & current_joint_state,
- const geometry_msgs::msg::Wrench & measured_wrench,
+ const MeasurementData & measurement_data,
trajectory_msgs::msg::JointTrajectoryPoint & joint_state_command
);
+ /**
+ * Update VIC input data (i.e., kinematics and parameters)
+ *
+ * Note: call only ONE of the update functions.
+ *
+ * \param[in] period time in seconds since last controller update
+ * \param[in] measurement_data most recent measurement data, including at
+ * least the joint position and velocity
+ */
+ controller_interface::return_type update_input_data(
+ const rclcpp::Duration & period,
+ const MeasurementData & measurement_data
+ );
+
/**
* Compute joint command from the current cartesian tracking errors
* and the desired interaction parameters (M, K, D). This function is
- * to be used when an external torque sensor is available.
+ * to be used when no external torque sensor is available.
*
* \param[in] period time in seconds since last controller update
- * \param[in] current_joint_state current joint state of the robot
- * \param[in] measured_wrench most recent measured wrench from force torque sensor
- * \param[in] measured_external_torques most recent measured external torques
* \param[out] joint_state_command computed joint state command
*/
- controller_interface::return_type update(
+ controller_interface::return_type compute_controls(
const rclcpp::Duration & period,
- const trajectory_msgs::msg::JointTrajectoryPoint & current_joint_state,
- const geometry_msgs::msg::Wrench & measured_wrench,
- const std::vector & measured_external_torques,
trajectory_msgs::msg::JointTrajectoryPoint & joint_state_command
);
/// Get current control mode (ADMITTANCE / IMPEDANCE / INVALID)
ControlMode get_control_mode() const {return control_mode_;}
-protected:
- /// Internal wrapper for the VIC logic
- controller_interface::return_type internal_update(
- const rclcpp::Duration & period,
- const trajectory_msgs::msg::JointTrajectoryPoint & current_joint_state,
- const geometry_msgs::msg::Wrench & measured_wrench,
- trajectory_msgs::msg::JointTrajectoryPoint & joint_state_command,
- bool use_external_torques = false
- );
+ /// Get current input data (call update_input_data() first)
+ const VicInputData & get_input_data() const {return vic_state_.input_data;}
+protected:
/// Manual setting of inertia, damping, and stiffness (diagonal matrices)
void set_interaction_parameters(
const Eigen::Matrix & desired_inertia,
@@ -159,9 +164,11 @@ class CartesianVicRule
std::shared_ptr parameter_handler_;
cartesian_vic_controller::Params parameters_;
+protected:
+ // ROS2 logging
+ rclcpp::Logger logger_;
rclcpp::Clock internal_clock_;
-protected:
template
void vec_to_eigen(const std::vector & data, T2 & matrix);
@@ -193,6 +200,8 @@ class CartesianVicRule
private:
/// Filtered wrench expressed in world frame
Eigen::Matrix wrench_world_;
+ /// Filtered wrench expressed in robot base frame
+ Eigen::Matrix wrench_base_;
/// Filtered external torques
Eigen::VectorXd filtered_external_torques_;
diff --git a/cartesian_vic_controller/include/cartesian_vic_controller/cartesian_vic_state.hpp b/cartesian_vic_controller/include/cartesian_vic_controller/cartesian_vic_state.hpp
index a74cac7..22133a2 100644
--- a/cartesian_vic_controller/include/cartesian_vic_controller/cartesian_vic_state.hpp
+++ b/cartesian_vic_controller/include/cartesian_vic_controller/cartesian_vic_state.hpp
@@ -63,6 +63,9 @@ class VicInputData
natural_joint_space_inertia = \
Eigen::Matrix::Zero(num_joints, num_joints);
*/
+ // Reset data availability
+ has_ft_sensor_ = false;
+ has_external_torque_sensor_ = false;
}
bool set_joint_state_external_torques(const Eigen::VectorXd & joint_state_external_torques)
{
@@ -75,28 +78,42 @@ class VicInputData
return true;
}
- bool get_joint_state_external_torques(Eigen::VectorXd & joint_state_external_torques) const
+ bool set_ft_sensor_wrench(const Eigen::Matrix & ft_sensor_wrench)
{
- if (!has_external_torque_sensor_) {
- joint_state_external_torques.setZero();
- return false;
- }
- if (joint_state_external_torques.size() != joint_state_external_torques_.size()) {
- joint_state_external_torques.setZero();
- return false;
- }
- joint_state_external_torques = joint_state_external_torques_;
+ robot_current_wrench_at_ft_frame_ = ft_sensor_wrench;
+ has_ft_sensor_ = true;
return true;
}
+
+ const Eigen::VectorXd & get_joint_state_external_torques() const
+ {
+ return joint_state_external_torques_;
+ }
+
+ const Eigen::Matrix & get_ft_sensor_wrench() const
+ {
+ return robot_current_wrench_at_ft_frame_;
+ }
+
bool reset_joint_state_external_torques()
{
has_external_torque_sensor_ = false;
return true;
}
+
+ bool reset_ft_sensor_wrench()
+ {
+ has_ft_sensor_ = false;
+ return true;
+ }
bool has_external_torque_sensor() const
{
return has_external_torque_sensor_;
}
+ bool has_ft_sensor() const
+ {
+ return has_ft_sensor_;
+ }
public:
// General parameters
@@ -133,7 +150,6 @@ class VicInputData
// Cartesian state (control frame w.r.t. robot base frame)
Eigen::Isometry3d robot_current_pose;
Eigen::Matrix robot_current_velocity;
- Eigen::Matrix robot_current_wrench_at_ft_frame; // ft_frame w.r.t. base
/// Natural inertia matrix (from dynamic model)
// Eigen::Matrix natural_cartesian_inertia;
@@ -141,6 +157,8 @@ class VicInputData
protected:
Eigen::VectorXd joint_state_external_torques_;
+ Eigen::Matrix robot_current_wrench_at_ft_frame_; // ft_frame w.r.t. base
+ bool has_ft_sensor_ = false;
bool has_external_torque_sensor_ = false;
};
diff --git a/cartesian_vic_controller/include/cartesian_vic_controller/measurement_data.hpp b/cartesian_vic_controller/include/cartesian_vic_controller/measurement_data.hpp
new file mode 100644
index 0000000..3baf385
--- /dev/null
+++ b/cartesian_vic_controller/include/cartesian_vic_controller/measurement_data.hpp
@@ -0,0 +1,123 @@
+// Copyright 2024 ICUBE Laboratory, University of Strasbourg
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+/// \authors: Thibault Poignonec
+
+#ifndef CARTESIAN_VIC_CONTROLLER__MEASUREMENT_DATA_HPP_
+#define CARTESIAN_VIC_CONTROLLER__MEASUREMENT_DATA_HPP_
+
+#include
+#include
+
+#include