3 #include <franka/duration.h>
4 #include <franka/robot_state.h>
12 using namespace movex;
14 template<
class RobotType>
16 double time {0.0}, motion_init_time {0.0};
33 throw std::runtime_error(
"joint impedance is not implemented yet.");
38 stiffness.bottomRightCorner(3, 3) << motion.
rotational_stiffness * Eigen::MatrixXd::Identity(3, 3);
41 damping.bottomRightCorner(3, 3) << 2.0 * sqrt(motion.
rotational_stiffness) * Eigen::MatrixXd::Identity(3, 3);
43 initial_state = robot->readOnce();
44 model =
new franka::Model(robot->loadModel());
46 initial_affine =
Affine(initial_state.O_T_EE);
47 position_d = Eigen::Vector3d(initial_affine.translation());
48 orientation_d = Eigen::Quaterniond(initial_affine.quaternion());
51 void init(
const franka::RobotState& robot_state, franka::Duration period) {
52 Eigen::Affine3d transform(Eigen::Matrix4d::Map(robot_state.O_T_EE.data()));
57 franka::Torques
operator()(
const franka::RobotState& robot_state, franka::Duration period) {
58 time += period.toSec();
60 init(robot_state, period);
63 std::array<double, 7> coriolis_array = model->coriolis(robot_state);
64 std::array<double, 42> jacobian_array = model->zeroJacobian(franka::Frame::kEndEffector, robot_state);
66 Eigen::Map<const Eigen::Matrix<double, 7, 1>> coriolis(coriolis_array.data());
67 Eigen::Map<const Eigen::Matrix<double, 6, 7>> jacobian(jacobian_array.data());
68 Eigen::Map<const Eigen::Matrix<double, 7, 1>> q(robot_state.q.data());
69 Eigen::Map<const Eigen::Matrix<double, 7, 1>> dq(robot_state.dq.data());
70 Eigen::Affine3d transform(Eigen::Matrix4d::Map(robot_state.O_T_EE.data()));
71 Eigen::Vector3d position(transform.translation());
72 Eigen::Quaterniond orientation(transform.linear());
74 Eigen::Matrix<double, 6, 1> error;
75 error.head(3) << position - position_d;
77 if (orientation_d.coeffs().dot(orientation.coeffs()) < 0.0) {
78 orientation.coeffs() << -orientation.coeffs();
81 Eigen::Quaterniond error_quaternion(orientation.inverse() * orientation_d);
82 error.tail(3) << error_quaternion.x(), error_quaternion.y(), error_quaternion.z();
83 error.tail(3) << -transform.linear() * error.tail(3);
85 Eigen::VectorXd wrench_cartesian(6), tau_task(7), tau_d(7);
86 wrench_cartesian = -stiffness * error - damping * (jacobian * dq);
90 switch (force_constraint.first) {
92 wrench_cartesian(0) = force_constraint.second;
95 wrench_cartesian(1) = force_constraint.second;
98 wrench_cartesian(2) = force_constraint.second;
103 tau_task << jacobian.transpose() * wrench_cartesian;
104 tau_d << tau_task + coriolis;
106 std::array<double, 7> tau_d_array{};
107 Eigen::VectorXd::Map(&tau_d_array[0], 7) = tau_d;
110 if (robot->stop_at_python_signal && Py_IsInitialized() && PyErr_CheckSignals() == -1) {
112 return franka::MotionFinished(franka::Torques(tau_d_array));
118 return franka::MotionFinished(franka::Torques(tau_d_array));
129 initial_affine =
Affine(Eigen::Affine3d(Eigen::Matrix4d::Map(initial_state.O_T_EE.data())));
130 motion_init_time = time;
135 if (transition_parameter <= 1.0) {
137 position_d = motion.
target.translation();
138 orientation_d = motion.
target.quaternion();
145 motion_init_time = time;
149 double time_diff = motion_init_time - time;
156 return franka::Torques(tau_d_array);