cartesian_impedance_example_controller.cpp
Go to the documentation of this file.
1 // Copyright (c) 2017 Franka Emika GmbH
2 // Use of this source code is governed by the Apache-2.0 license, see LICENSE
4 
5 #include <cmath>
6 #include <memory>
7 
9 #include <franka/robot_state.h>
11 #include <ros/ros.h>
12 
14 
16 
18  ros::NodeHandle& node_handle) {
19  std::vector<double> cartesian_stiffness_vector;
20  std::vector<double> cartesian_damping_vector;
21 
22  sub_equilibrium_pose_ = node_handle.subscribe(
24  ros::TransportHints().reliable().tcpNoDelay());
25 
26  std::string arm_id;
27  if (!node_handle.getParam("arm_id", arm_id)) {
28  ROS_ERROR_STREAM("CartesianImpedanceExampleController: Could not read parameter arm_id");
29  return false;
30  }
31  std::vector<std::string> joint_names;
32  if (!node_handle.getParam("joint_names", joint_names) || joint_names.size() != 7) {
33  ROS_ERROR(
34  "CartesianImpedanceExampleController: Invalid or no joint_names parameters provided, "
35  "aborting controller init!");
36  return false;
37  }
38 
39  auto* model_interface = robot_hw->get<franka_hw::FrankaModelInterface>();
40  if (model_interface == nullptr) {
42  "CartesianImpedanceExampleController: Error getting model interface from hardware");
43  return false;
44  }
45  try {
46  model_handle_ = std::make_unique<franka_hw::FrankaModelHandle>(
47  model_interface->getHandle(arm_id + "_model"));
50  "CartesianImpedanceExampleController: Exception getting model handle from interface: "
51  << ex.what());
52  return false;
53  }
54 
55  auto* state_interface = robot_hw->get<franka_hw::FrankaStateInterface>();
56  if (state_interface == nullptr) {
58  "CartesianImpedanceExampleController: Error getting state interface from hardware");
59  return false;
60  }
61  try {
62  state_handle_ = std::make_unique<franka_hw::FrankaStateHandle>(
63  state_interface->getHandle(arm_id + "_robot"));
66  "CartesianImpedanceExampleController: Exception getting state handle from interface: "
67  << ex.what());
68  return false;
69  }
70 
71  auto* effort_joint_interface = robot_hw->get<hardware_interface::EffortJointInterface>();
72  if (effort_joint_interface == nullptr) {
74  "CartesianImpedanceExampleController: Error getting effort joint interface from hardware");
75  return false;
76  }
77  for (size_t i = 0; i < 7; ++i) {
78  try {
79  joint_handles_.push_back(effort_joint_interface->getHandle(joint_names[i]));
82  "CartesianImpedanceExampleController: Exception getting joint handles: " << ex.what());
83  return false;
84  }
85  }
86 
88  ros::NodeHandle(node_handle.getNamespace() + "/dynamic_reconfigure_compliance_param_node");
89 
90  dynamic_server_compliance_param_ = std::make_unique<
91  dynamic_reconfigure::Server<franka_example_controllers::compliance_paramConfig>>(
92 
96 
97  position_d_.setZero();
98  orientation_d_.coeffs() << 0.0, 0.0, 0.0, 1.0;
99  position_d_target_.setZero();
100  orientation_d_target_.coeffs() << 0.0, 0.0, 0.0, 1.0;
101 
102  cartesian_stiffness_.setZero();
103  cartesian_damping_.setZero();
104 
105  return true;
106 }
107 
109  // compute initial velocity with jacobian and set x_attractor and q_d_nullspace
110  // to initial configuration
111  franka::RobotState initial_state = state_handle_->getRobotState();
112  // get jacobian
113  std::array<double, 42> jacobian_array =
114  model_handle_->getZeroJacobian(franka::Frame::kEndEffector);
115  // convert to eigen
116  Eigen::Map<Eigen::Matrix<double, 7, 1>> q_initial(initial_state.q.data());
117  Eigen::Affine3d initial_transform(Eigen::Matrix4d::Map(initial_state.O_T_EE.data()));
118 
119  // set equilibrium point to current state
120  position_d_ = initial_transform.translation();
121  orientation_d_ = Eigen::Quaterniond(initial_transform.rotation());
122  position_d_target_ = initial_transform.translation();
123  orientation_d_target_ = Eigen::Quaterniond(initial_transform.rotation());
124 
125  // set nullspace equilibrium configuration to initial q
126  q_d_nullspace_ = q_initial;
127 }
128 
130  const ros::Duration& /*period*/) {
131  // get state variables
132  franka::RobotState robot_state = state_handle_->getRobotState();
133  std::array<double, 7> coriolis_array = model_handle_->getCoriolis();
134  std::array<double, 42> jacobian_array =
135  model_handle_->getZeroJacobian(franka::Frame::kEndEffector);
136 
137  // convert to Eigen
138  Eigen::Map<Eigen::Matrix<double, 7, 1>> coriolis(coriolis_array.data());
139  Eigen::Map<Eigen::Matrix<double, 6, 7>> jacobian(jacobian_array.data());
140  Eigen::Map<Eigen::Matrix<double, 7, 1>> q(robot_state.q.data());
141  Eigen::Map<Eigen::Matrix<double, 7, 1>> dq(robot_state.dq.data());
142  Eigen::Map<Eigen::Matrix<double, 7, 1>> tau_J_d( // NOLINT (readability-identifier-naming)
143  robot_state.tau_J_d.data());
144  Eigen::Affine3d transform(Eigen::Matrix4d::Map(robot_state.O_T_EE.data()));
145  Eigen::Vector3d position(transform.translation());
146  Eigen::Quaterniond orientation(transform.rotation());
147 
148  // compute error to desired pose
149  // position error
150  Eigen::Matrix<double, 6, 1> error;
151  error.head(3) << position - position_d_;
152 
153  // orientation error
154  if (orientation_d_.coeffs().dot(orientation.coeffs()) < 0.0) {
155  orientation.coeffs() << -orientation.coeffs();
156  }
157  // "difference" quaternion
158  Eigen::Quaterniond error_quaternion(orientation.inverse() * orientation_d_);
159  error.tail(3) << error_quaternion.x(), error_quaternion.y(), error_quaternion.z();
160  // Transform to base frame
161  error.tail(3) << -transform.rotation() * error.tail(3);
162 
163  // compute control
164  // allocate variables
165  Eigen::VectorXd tau_task(7), tau_nullspace(7), tau_d(7);
166 
167  // pseudoinverse for nullspace handling
168  // kinematic pseuoinverse
169  Eigen::MatrixXd jacobian_transpose_pinv;
170  pseudoInverse(jacobian.transpose(), jacobian_transpose_pinv);
171 
172  // Cartesian PD control with damping ratio = 1
173  tau_task << jacobian.transpose() *
174  (-cartesian_stiffness_ * error - cartesian_damping_ * (jacobian * dq));
175  // nullspace PD control with damping ratio = 1
176  tau_nullspace << (Eigen::MatrixXd::Identity(7, 7) -
177  jacobian.transpose() * jacobian_transpose_pinv) *
179  (2.0 * sqrt(nullspace_stiffness_)) * dq);
180  // Desired torque
181  tau_d << tau_task + tau_nullspace + coriolis;
182  // Saturate torque rate to avoid discontinuities
183  tau_d << saturateTorqueRate(tau_d, tau_J_d);
184  for (size_t i = 0; i < 7; ++i) {
185  joint_handles_[i].setCommand(tau_d(i));
186  }
187 
188  // update parameters changed online either through dynamic reconfigure or through the interactive
189  // target by filtering
196  std::lock_guard<std::mutex> position_d_target_mutex_lock(
200 }
201 
203  const Eigen::Matrix<double, 7, 1>& tau_d_calculated,
204  const Eigen::Matrix<double, 7, 1>& tau_J_d) { // NOLINT (readability-identifier-naming)
205  Eigen::Matrix<double, 7, 1> tau_d_saturated{};
206  for (size_t i = 0; i < 7; i++) {
207  double difference = tau_d_calculated[i] - tau_J_d[i];
208  tau_d_saturated[i] =
209  tau_J_d[i] + std::max(std::min(difference, delta_tau_max_), -delta_tau_max_);
210  }
211  return tau_d_saturated;
212 }
213 
215  franka_example_controllers::compliance_paramConfig& config,
216  uint32_t /*level*/) {
217  cartesian_stiffness_target_.setIdentity();
218  cartesian_stiffness_target_.topLeftCorner(3, 3)
219  << config.translational_stiffness * Eigen::Matrix3d::Identity();
220  cartesian_stiffness_target_.bottomRightCorner(3, 3)
221  << config.rotational_stiffness * Eigen::Matrix3d::Identity();
222  cartesian_damping_target_.setIdentity();
223  // Damping ratio = 1
224  cartesian_damping_target_.topLeftCorner(3, 3)
225  << 2.0 * sqrt(config.translational_stiffness) * Eigen::Matrix3d::Identity();
226  cartesian_damping_target_.bottomRightCorner(3, 3)
227  << 2.0 * sqrt(config.rotational_stiffness) * Eigen::Matrix3d::Identity();
228  nullspace_stiffness_target_ = config.nullspace_stiffness;
229 }
230 
232  const geometry_msgs::PoseStampedConstPtr& msg) {
233  std::lock_guard<std::mutex> position_d_target_mutex_lock(
235  position_d_target_ << msg->pose.position.x, msg->pose.position.y, msg->pose.position.z;
236  Eigen::Quaterniond last_orientation_d_target(orientation_d_target_);
237  orientation_d_target_.coeffs() << msg->pose.orientation.x, msg->pose.orientation.y,
238  msg->pose.orientation.z, msg->pose.orientation.w;
239  if (last_orientation_d_target.coeffs().dot(orientation_d_target_.coeffs()) < 0.0) {
240  orientation_d_target_.coeffs() << -orientation_d_target_.coeffs();
241  }
242 }
243 
244 } // namespace franka_example_controllers
245 
franka_example_controllers::CartesianImpedanceExampleController
Definition: cartesian_impedance_example_controller.h:25
franka_example_controllers::CartesianImpedanceExampleController::cartesian_stiffness_
Eigen::Matrix< double, 6, 6 > cartesian_stiffness_
Definition: cartesian_impedance_example_controller.h:48
franka_example_controllers::CartesianImpedanceExampleController::dynamic_reconfigure_compliance_param_node_
ros::NodeHandle dynamic_reconfigure_compliance_param_node_
Definition: cartesian_impedance_example_controller.h:62
ROS_ERROR_STREAM
#define ROS_ERROR_STREAM(args)
pseudo_inversion.h
hardware_interface::HardwareInterfaceException::what
const char * what() const noexcept override
hardware_interface::InterfaceManager::get
T * get()
ros::NodeHandle::getParam
bool getParam(const std::string &key, bool &b) const
ros.h
franka_example_controllers::pseudoInverse
void pseudoInverse(const Eigen::MatrixXd &M_, Eigen::MatrixXd &M_pinv_, bool damped=true)
Definition: pseudo_inversion.h:16
franka_example_controllers::CartesianImpedanceExampleController::starting
void starting(const ros::Time &) override
Definition: cartesian_impedance_example_controller.cpp:108
franka_example_controllers::CartesianImpedanceExampleController::nullspace_stiffness_target_
double nullspace_stiffness_target_
Definition: cartesian_impedance_example_controller.h:46
franka_example_controllers::CartesianImpedanceExampleController::init
bool init(hardware_interface::RobotHW *robot_hw, ros::NodeHandle &node_handle) override
Definition: cartesian_impedance_example_controller.cpp:17
ros::TransportHints
franka_example_controllers::CartesianImpedanceExampleController::cartesian_stiffness_target_
Eigen::Matrix< double, 6, 6 > cartesian_stiffness_target_
Definition: cartesian_impedance_example_controller.h:49
class_list_macros.h
controller_interface::ControllerBase
cartesian_impedance_example_controller.h
franka_example_controllers::CartesianImpedanceExampleController::complianceParamCallback
void complianceParamCallback(franka_example_controllers::compliance_paramConfig &config, uint32_t level)
Definition: cartesian_impedance_example_controller.cpp:214
franka_example_controllers
Definition: cartesian_impedance_example_controller.h:23
franka_example_controllers::CartesianImpedanceExampleController::orientation_d_target_
Eigen::Quaterniond orientation_d_target_
Definition: cartesian_impedance_example_controller.h:57
PLUGINLIB_EXPORT_CLASS
#define PLUGINLIB_EXPORT_CLASS(class_type, base_class_type)
franka_example_controllers::CartesianImpedanceExampleController::dynamic_server_compliance_param_
std::unique_ptr< dynamic_reconfigure::Server< franka_example_controllers::compliance_paramConfig > > dynamic_server_compliance_param_
Definition: cartesian_impedance_example_controller.h:61
franka_example_controllers::CartesianImpedanceExampleController::nullspace_stiffness_
double nullspace_stiffness_
Definition: cartesian_impedance_example_controller.h:45
hardware_interface::RobotHW
franka_example_controllers::CartesianImpedanceExampleController::joint_handles_
std::vector< hardware_interface::JointHandle > joint_handles_
Definition: cartesian_impedance_example_controller.h:42
controller_base.h
franka_example_controllers::CartesianImpedanceExampleController::model_handle_
std::unique_ptr< franka_hw::FrankaModelHandle > model_handle_
Definition: cartesian_impedance_example_controller.h:41
arm_id
std::string arm_id
franka_example_controllers::CartesianImpedanceExampleController::equilibriumPoseCallback
void equilibriumPoseCallback(const geometry_msgs::PoseStampedConstPtr &msg)
Definition: cartesian_impedance_example_controller.cpp:231
franka_example_controllers::CartesianImpedanceExampleController::cartesian_damping_target_
Eigen::Matrix< double, 6, 6 > cartesian_damping_target_
Definition: cartesian_impedance_example_controller.h:51
ROS_ERROR
#define ROS_ERROR(...)
franka_example_controllers::CartesianImpedanceExampleController::update
void update(const ros::Time &, const ros::Duration &period) override
Definition: cartesian_impedance_example_controller.cpp:129
franka_hw::FrankaStateInterface
hardware_interface::EffortJointInterface
ros::NodeHandle::subscribe
Subscriber subscribe(const std::string &topic, uint32_t queue_size, const boost::function< void(C)> &callback, const VoidConstPtr &tracked_object=VoidConstPtr(), const TransportHints &transport_hints=TransportHints())
franka_example_controllers::CartesianImpedanceExampleController::sub_equilibrium_pose_
ros::Subscriber sub_equilibrium_pose_
Definition: cartesian_impedance_example_controller.h:67
franka_example_controllers::CartesianImpedanceExampleController::state_handle_
std::unique_ptr< franka_hw::FrankaStateHandle > state_handle_
Definition: cartesian_impedance_example_controller.h:40
franka_hw::FrankaModelInterface
hardware_interface::HardwareInterfaceException
ros::Time
franka_example_controllers::CartesianImpedanceExampleController::position_and_orientation_d_target_mutex_
std::mutex position_and_orientation_d_target_mutex_
Definition: cartesian_impedance_example_controller.h:55
joint_names
std::array< std::string, 7 > joint_names
franka_example_controllers::CartesianImpedanceExampleController::saturateTorqueRate
Eigen::Matrix< double, 7, 1 > saturateTorqueRate(const Eigen::Matrix< double, 7, 1 > &tau_d_calculated, const Eigen::Matrix< double, 7, 1 > &tau_J_d)
Definition: cartesian_impedance_example_controller.cpp:202
ros::NodeHandle::getNamespace
const std::string & getNamespace() const
franka_example_controllers::CartesianImpedanceExampleController::orientation_d_
Eigen::Quaterniond orientation_d_
Definition: cartesian_impedance_example_controller.h:54
franka_example_controllers::CartesianImpedanceExampleController::q_d_nullspace_
Eigen::Matrix< double, 7, 1 > q_d_nullspace_
Definition: cartesian_impedance_example_controller.h:52
franka_example_controllers::CartesianImpedanceExampleController::position_d_
Eigen::Vector3d position_d_
Definition: cartesian_impedance_example_controller.h:53
ros::Duration
franka_example_controllers::CartesianImpedanceExampleController::cartesian_damping_
Eigen::Matrix< double, 6, 6 > cartesian_damping_
Definition: cartesian_impedance_example_controller.h:50
ros::NodeHandle
franka_example_controllers::CartesianImpedanceExampleController::filter_params_
double filter_params_
Definition: cartesian_impedance_example_controller.h:44
franka_example_controllers::CartesianImpedanceExampleController::position_d_target_
Eigen::Vector3d position_d_target_
Definition: cartesian_impedance_example_controller.h:56
franka_example_controllers::CartesianImpedanceExampleController::delta_tau_max_
const double delta_tau_max_
Definition: cartesian_impedance_example_controller.h:47
error
def error(*args, **kwargs)


franka_example_controllers
Author(s): Franka Emika GmbH
autogenerated on Mon Sep 19 2022 02:33:26