3 #include <franka/duration.h>
4 #include <franka/robot_state.h>
9 #include <ruckig/ruckig.hpp>
13 using namespace movex;
16 template<
class RobotType>
18 ruckig::Ruckig<RobotType::degrees_of_freedoms> trajectory_generator {RobotType::control_rate};
19 ruckig::InputParameter<RobotType::degrees_of_freedoms>
input_para;
20 ruckig::OutputParameter<RobotType::degrees_of_freedoms>
output_para;
25 bool waypoint_has_elbow {
false};
37 bool set_target_at_zero_time {
true};
39 const size_t cooldown_iterations {5};
40 size_t current_cooldown_iteration {0};
46 current_cooldown_iteration = 0;
47 set_target_at_zero_time =
false;
50 void init(
const franka::RobotState& robot_state, franka::Duration period) {
51 franka::CartesianPose initial_cartesian_pose(robot_state.O_T_EE_c, robot_state.elbow_c);
52 Affine initial_pose(initial_cartesian_pose.O_T_EE);
54 Vector7d initial_vector = initial_pose.vector_with_elbow(initial_cartesian_pose.elbow[0]);
55 Vector7d initial_velocity = (
Vector7d() << robot_state.O_dP_EE_c[0], robot_state.O_dP_EE_c[1], robot_state.O_dP_EE_c[2], robot_state.O_dP_EE_c[3], robot_state.O_dP_EE_c[4], robot_state.O_dP_EE_c[5], robot_state.delbow_c[0]).finished();
57 old_affine = initial_pose;
58 old_vector = initial_vector;
59 old_elbow = old_vector(6);
61 input_para.current_position = toStd(initial_vector);
62 input_para.current_velocity = toStd(initial_velocity);
63 input_para.current_acceleration = toStd(Vector7d::Zero());
66 setInputLimits(input_para, robot, data);
68 if (set_target_at_zero_time) {
69 waypoint_iterator = current_motion.
waypoints.begin();
71 const auto current_waypoint = *waypoint_iterator;
72 waypoint_has_elbow = current_waypoint.elbow.has_value();
73 auto target_position_vector = current_waypoint.getTargetVector(frame, old_affine, old_elbow);
75 input_para.enabled = {
true,
true,
true,
true,
true,
true, waypoint_has_elbow};
76 input_para.target_position = toStd(target_position_vector);
77 input_para.target_velocity = toStd(Vector7d::Zero());
78 setInputLimits(input_para, robot, current_waypoint, data);
80 old_affine = current_waypoint.getTargetAffine(frame, old_affine);
81 old_vector = target_position_vector;
82 old_elbow = old_vector(6);
86 franka::CartesianPose
operator()(
const franka::RobotState& robot_state, franka::Duration period) {
87 time += period.toSec();
89 init(robot_state, period);
93 if (reaction.has_fired) {
98 std::cout <<
"[frankx] reaction fired." << std::endl;
99 reaction.has_fired =
true;
101 bool new_motion =
false;
103 if (reaction.waypoint_action.has_value()) {
106 }
else if (reaction.waypoint_motion.has_value()) {
108 current_motion = *(reaction.waypoint_motion.value());
114 waypoint_iterator = current_motion.
waypoints.begin();
116 franka::CartesianPose current_cartesian_pose(robot_state.O_T_EE_c, robot_state.elbow_c);
117 Affine current_pose(current_cartesian_pose.O_T_EE);
118 auto current_vector = current_pose.vector_with_elbow(current_cartesian_pose.elbow[0]);
119 old_affine = current_pose;
120 old_vector = current_vector;
121 old_elbow = old_vector(6);
123 const auto current_waypoint = *waypoint_iterator;
124 waypoint_has_elbow = current_waypoint.elbow.has_value();
125 auto target_position_vector = current_waypoint.getTargetVector(
Affine(), old_affine, old_elbow);
127 input_para.enabled = {
true,
true,
true,
true,
true,
true, waypoint_has_elbow};
128 input_para.target_position = toStd(target_position_vector);
129 input_para.target_velocity = toStd(Vector7d::Zero());
130 setInputLimits(input_para, robot, current_waypoint, data);
132 old_affine = current_waypoint.getTargetAffine(
Affine(), old_affine);
133 old_vector = target_position_vector;
134 old_elbow = old_vector(6);
142 if (robot->stop_at_python_signal && Py_IsInitialized() && PyErr_CheckSignals() == -1) {
147 const int steps = std::max<int>(period.toMSec(), 1);
148 for (
int i = 0; i < steps; i++) {
149 result = trajectory_generator.update(input_para, output_para);
151 if (motion.
reload || result == ruckig::Result::Finished) {
152 bool has_new_waypoint {
false};
154 if (waypoint_iterator != current_motion.
waypoints.end()) {
156 has_new_waypoint = (waypoint_iterator != current_motion.
waypoints.end());
161 if (current_cooldown_iteration < cooldown_iterations) {
162 current_cooldown_iteration += 1;
168 }
else if (motion.
reload) {
169 current_motion = motion;
170 waypoint_iterator = current_motion.
waypoints.begin();
172 current_motion.
reload =
false;
173 has_new_waypoint =
true;
176 if (has_new_waypoint) {
177 const auto current_waypoint = *waypoint_iterator;
178 waypoint_has_elbow = current_waypoint.elbow.has_value();
179 auto target_position_vector = current_waypoint.getTargetVector(frame, old_affine, old_elbow);
181 input_para.enabled = {
true,
true,
true,
true,
true,
true, waypoint_has_elbow};
182 input_para.target_position = toStd(target_position_vector);
183 input_para.target_velocity = toStd(Vector7d::Zero());
184 setInputLimits<RobotType>(input_para, robot, current_waypoint, data);
186 old_affine = current_waypoint.getTargetAffine(frame, old_affine);
187 old_vector = target_position_vector;
188 old_elbow = old_vector(6);
191 }
else if (result == ruckig::Result::Error) {
192 std::cout <<
"[frankx robot] Invalid inputs:" << std::endl;
196 output_para.pass_to_input(input_para);