@@ -73,7 +73,7 @@ FrankaConfig* Franka::get_config() {
7373
7474FrankaState* Franka::get_state () {
7575 franka::RobotState current_robot_state;
76- if (this ->running_controller == Controller::none) {
76+ if (this ->running_controller . load () == Controller::none) {
7777 current_robot_state = this ->robot .readOnce ();
7878 } else {
7979 std::lock_guard<std::mutex> lock (this ->interpolator_mutex );
@@ -100,7 +100,7 @@ void Franka::set_default_robot_behavior() {
100100common::Pose Franka::get_cartesian_position () {
101101 this ->check_for_background_errors ();
102102 common::Pose x;
103- if (this ->running_controller == Controller::none) {
103+ if (this ->running_controller . load () == Controller::none) {
104104 this ->curr_state = this ->robot .readOnce ();
105105 x = common::Pose (this ->curr_state .O_T_EE );
106106 } else {
@@ -127,7 +127,7 @@ void Franka::set_joint_position(const common::VectorXd& q) {
127127common::VectorXd Franka::get_joint_position () {
128128 this ->check_for_background_errors ();
129129 common::Vector7d joints;
130- if (this ->running_controller == Controller::none) {
130+ if (this ->running_controller . load () == Controller::none) {
131131 this ->curr_state = this ->robot .readOnce ();
132132 joints = common::Vector7d (this ->curr_state .q .data ());
133133 } else {
@@ -182,15 +182,15 @@ void Franka::controller_set_joint_position(const common::Vector7d& desired_q) {
182182 int policy_rate = 20 ;
183183 int traj_rate = 500 ;
184184
185- if (this ->running_controller == Controller::none) {
185+ if (this ->running_controller . load () == Controller::none) {
186186 this ->controller_time = 0.0 ;
187187 this ->get_joint_position ();
188188 this ->joint_interpolator = common::LinearJointPositionTrajInterpolator ();
189- } else if (this ->running_controller != Controller::jsc) {
189+ } else if (this ->running_controller . load () != Controller::jsc) {
190190 // runtime error
191191 throw std::runtime_error (
192192 " Controller type must but joint space but is " +
193- std::to_string (this ->running_controller ) +
193+ std::to_string (static_cast < int >( this ->running_controller . load ()) ) +
194194 " . To change controller type stop the current controller first." );
195195 } else {
196196 this ->interpolator_mutex .lock ();
@@ -202,8 +202,8 @@ void Franka::controller_set_joint_position(const common::Vector7d& desired_q) {
202202 policy_rate, traj_rate, traj_interpolation_time_fraction);
203203
204204 // if not thread is running, then start
205- if (this ->running_controller == Controller::none) {
206- this ->running_controller = Controller::jsc;
205+ if (this ->running_controller . load () == Controller::none) {
206+ this ->running_controller . store ( Controller::jsc) ;
207207 this ->control_thread = std::thread (&Franka::joint_controller, this );
208208 } else {
209209 this ->interpolator_mutex .unlock ();
@@ -229,28 +229,35 @@ void Franka::osc_set_cartesian_position(
229229 int policy_rate = 20 ;
230230 int traj_rate = 500 ;
231231
232- if (this ->running_controller == Controller::none) {
232+ if (this ->running_controller . load () == Controller::none) {
233233 this ->controller_time = 0.0 ;
234+ {
235+ std::lock_guard<std::mutex> lock (this ->interpolator_mutex );
236+ this ->curr_state = this ->robot .readOnce ();
237+ }
234238 this ->traj_interpolator = common::LinearPoseTrajInterpolator ();
235- } else if (this ->running_controller != Controller::osc) {
239+ } else if (this ->running_controller . load () != Controller::osc) {
236240 throw std::runtime_error (
237241 " Controller type must but osc but is " +
238- std::to_string (this ->running_controller ) +
242+ std::to_string (static_cast < int >( this ->running_controller . load ()) ) +
239243 " . To change controller type stop the current controller first." );
240244 } else {
241245 this ->interpolator_mutex .lock ();
242246 }
243247
244248 common::Pose curr_pose (this ->curr_state .O_T_EE );
249+ if (!this ->m_cfg .tcp_offset_configured_in_desk ) {
250+ curr_pose = curr_pose * this ->m_cfg .tcp_offset ;
251+ }
245252 this ->traj_interpolator .reset (
246253 this ->controller_time , curr_pose.translation (), curr_pose.quaternion (),
247254 desired_pose_EE_in_base_frame.translation (),
248255 desired_pose_EE_in_base_frame.quaternion (), policy_rate, traj_rate,
249256 traj_interpolation_time_fraction);
250257
251258 // if not thread is running, then start
252- if (this ->running_controller == Controller::none) {
253- this ->running_controller = Controller::osc;
259+ if (this ->running_controller . load () == Controller::none) {
260+ this ->running_controller . store ( Controller::osc) ;
254261 this ->control_thread = std::thread (&Franka::osc, this );
255262 } else {
256263 this ->interpolator_mutex .unlock ();
@@ -259,10 +266,11 @@ void Franka::osc_set_cartesian_position(
259266
260267// method to stop thread
261268void Franka::stop_control_thread () {
262- if (this ->control_thread .has_value () &&
263- this ->running_controller != Controller::none) {
264- this ->running_controller = Controller::none;
265- this ->control_thread ->join ();
269+ if (this ->control_thread .has_value ()) {
270+ this ->running_controller .store (Controller::none);
271+ if (this ->control_thread ->joinable ()) {
272+ this ->control_thread ->join ();
273+ }
266274 this ->control_thread .reset ();
267275 }
268276}
@@ -291,7 +299,10 @@ void Franka::osc() {
291299 // translation: [150.0, 150.0, 150.0]
292300 // rotation: 250.0
293301
294- Eigen::Matrix<double , 3 , 3 > Kp_p, Kp_r, Kd_p, Kd_r;
302+ Eigen::Matrix<double , 3 , 3 > Kp_p = Eigen::Matrix3d::Zero ();
303+ Eigen::Matrix<double , 3 , 3 > Kp_r = Eigen::Matrix3d::Zero ();
304+ Eigen::Matrix<double , 3 , 3 > Kd_p = Eigen::Matrix3d::Zero ();
305+ Eigen::Matrix<double , 3 , 3 > Kd_r = Eigen::Matrix3d::Zero ();
295306 Eigen::Matrix<double , 7 , 1 > static_q_task_;
296307 Eigen::Matrix<double , 7 , 1 > residual_mass_vec_;
297308 Eigen::Array<double , 7 , 1 > joint_max_;
@@ -323,7 +334,7 @@ void Franka::osc() {
323334 std::chrono::high_resolution_clock::now ();
324335
325336 // torques handler
326- if (this ->running_controller == Controller::none) {
337+ if (this ->running_controller . load () == Controller::none) {
327338 franka::Torques zero_torques{{0.0 , 0.0 , 0.0 , 0.0 , 0.0 , 0.0 , 0.0 }};
328339 return franka::MotionFinished (zero_torques);
329340 }
@@ -335,7 +346,6 @@ void Franka::osc() {
335346 Eigen::Vector3d desired_pos_EE_in_base_frame;
336347 Eigen::Quaterniond desired_quat_EE_in_base_frame;
337348
338- common::Pose pose (robot_state.O_T_EE );
339349 // form deoxys/config/charmander.yml
340350 int policy_rate = 20 ;
341351 int traj_rate = 500 ;
@@ -376,9 +386,15 @@ void Franka::osc() {
376386 jacobian_pos << jacobian.block (0 , 0 , 3 , 7 );
377387 jacobian_ori << jacobian.block (3 , 0 , 3 , 7 );
378388
379- // End effector pose in base frame
380- Eigen::Affine3d T_EE_in_base_frame (
381- Eigen::Matrix4d::Map (robot_state.O_T_EE .data ()));
389+ // Express OSC feedback in the same TCP frame exposed by the public
390+ // Cartesian API.
391+ common::Pose T_EE_in_base_frame_pose =
392+ this ->m_cfg .tcp_offset_configured_in_desk
393+ ? common::Pose (robot_state.O_T_EE )
394+ : common::Pose (robot_state.O_T_EE ) * this ->m_cfg .tcp_offset ;
395+ Eigen::Affine3d T_EE_in_base_frame =
396+ T_EE_in_base_frame_pose.affine_matrix ();
397+
382398 Eigen::Vector3d pos_EE_in_base_frame (T_EE_in_base_frame.translation ());
383399 Eigen::Quaterniond quat_EE_in_base_frame (T_EE_in_base_frame.linear ());
384400
@@ -487,7 +503,7 @@ void Franka::osc() {
487503 }
488504
489505 // Ensure we mark the controller as stopped so we can restart later
490- this ->running_controller = Controller::none;
506+ this ->running_controller . store ( Controller::none) ;
491507}
492508
493509void Franka::joint_controller () {
@@ -524,14 +540,13 @@ void Franka::joint_controller() {
524540 std::chrono::high_resolution_clock::now ();
525541
526542 // torques handler
527- if (this ->running_controller == Controller::none) {
543+ if (this ->running_controller . load () == Controller::none) {
528544 // TODO: test if this also works when the robot is moving
529545 franka::Torques zero_torques{{0.0 , 0.0 , 0.0 , 0.0 , 0.0 , 0.0 , 0.0 }};
530546 return franka::MotionFinished (zero_torques);
531547 }
532548
533549 common::Vector7d desired_q;
534- common::Pose pose (robot_state.O_T_EE );
535550
536551 this ->interpolator_mutex .lock ();
537552 this ->curr_state = robot_state;
@@ -588,16 +603,18 @@ void Franka::joint_controller() {
588603 std::lock_guard<std::mutex> lock (this ->exception_mutex );
589604 this ->background_exception = std::current_exception ();
590605 }
606+
607+ this ->running_controller .store (Controller::none);
591608}
592609
593610void Franka::zero_torque_guiding () {
594611 this ->check_for_background_errors ();
595- if (this ->running_controller != Controller::none) {
612+ if (this ->running_controller . load () != Controller::none) {
596613 throw std::runtime_error (
597614 " A controller is currently running. Please stop it first." );
598615 }
599616 this ->controller_time = 0.0 ;
600- this ->running_controller = Controller::ztc;
617+ this ->running_controller . store ( Controller::ztc) ;
601618 this ->control_thread = std::thread (&Franka::zero_torque_controller, this );
602619}
603620
@@ -617,7 +634,7 @@ void Franka::zero_torque_controller() {
617634 this ->curr_state = robot_state;
618635 this ->controller_time += period.toSec ();
619636 this ->interpolator_mutex .unlock ();
620- if (this ->running_controller == Controller::none) {
637+ if (this ->running_controller . load () == Controller::none) {
621638 // stop
622639 return franka::MotionFinished (franka::Torques ({0 , 0 , 0 , 0 , 0 , 0 , 0 }));
623640 }
@@ -627,6 +644,8 @@ void Franka::zero_torque_controller() {
627644 std::lock_guard<std::mutex> lock (this ->exception_mutex );
628645 this ->background_exception = std::current_exception ();
629646 }
647+
648+ this ->running_controller .store (Controller::none);
630649}
631650
632651void Franka::move_home () {
@@ -714,8 +733,12 @@ std::optional<std::shared_ptr<common::Kinematics>> Franka::get_ik() {
714733
715734void Franka::set_cartesian_position (const common::Pose& x) {
716735 // pose is assumed to be in the robots coordinate frame
736+ common::Pose target_pose = x;
737+ if (!this ->m_cfg .tcp_offset_configured_in_desk ) {
738+ target_pose = target_pose * this ->m_cfg .tcp_offset .inverse ();
739+ }
717740 if (this ->m_cfg .async_control ) {
718- this ->osc_set_cartesian_position (x );
741+ this ->osc_set_cartesian_position (target_pose );
719742 return ;
720743 }
721744 // TODO: this should handled with tcp offset config
@@ -733,10 +756,11 @@ void Franka::set_cartesian_position(const common::Pose& x) {
733756 // if gripper is attached the tcp offset will automatically be applied
734757 // by libfranka
735758 this ->robot .setEE (nominal_end_effector_frame_value.affine_array ());
736- this ->set_cartesian_position_internal (x, 1.0 , std::nullopt , std::nullopt );
759+ this ->set_cartesian_position_internal (target_pose, 1.0 , std::nullopt ,
760+ std::nullopt );
737761
738762 } else if (this ->m_cfg .ik_solver == IKSolver::rcs_ik) {
739- this ->set_cartesian_position_ik (x );
763+ this ->set_cartesian_position_ik (target_pose );
740764 }
741765}
742766
@@ -786,14 +810,17 @@ void Franka::set_cartesian_position_internal(const common::Pose& pose,
786810
787811 this ->robot .control (
788812 [&force_stop_condition, &initial_elbow, &elbow, &max_force, &time,
789- &max_time, &initial_pose, &should_stop,
813+ &max_time, &initial_pose, &should_stop, this ,
790814 &pose](const franka::RobotState& state,
791815 franka::Duration time_step) -> franka::CartesianPose {
792816 time += time_step.toSec ();
793817 if (time == 0 ) {
794818 initial_elbow = state.elbow_c ;
795819
796- initial_pose = common::Pose (state.O_T_EE );
820+ initial_pose =
821+ this ->m_cfg .tcp_offset_configured_in_desk
822+ ? common::Pose (state.O_T_EE )
823+ : common::Pose (state.O_T_EE ) * this ->m_cfg .tcp_offset ;
797824 }
798825 auto new_elbow = initial_elbow;
799826 const double progress = time / max_time;
0 commit comments