franky 1.1.4
A High-Level Motion API for Franka
Loading...
Searching...
No Matches
robot.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <franka/control_types.h>
4#include <franka/duration.h>
5#include <franka/exception.h>
6#include <franka/robot.h>
7#include <franka/robot_state.h>
8
9#include <exception>
10#include <future>
11#include <optional>
12#include <stdexcept>
13#include <variant>
14
19#include "franky/model.hpp"
23#include "franky/robot_pose.hpp"
26#include "franky/types.hpp"
27#include "franky/util.hpp"
29
30namespace franky {
31
38struct InvalidMotionTypeException : std::runtime_error {
39 using std::runtime_error::runtime_error;
40};
41
48struct MotionReuseException : std::runtime_error {
49 using std::runtime_error::runtime_error;
50};
51
58class Robot : public franka::Robot {
59 public:
63 struct Params {
71
76
81
87 franka::ControllerMode controller_mode{franka::ControllerMode::kJointImpedance};
88
94 franka::RealtimeConfig realtime_config{franka::RealtimeConfig::kEnforce};
95
99 double kalman_q_process_var = 0.0001;
100
104 double kalman_dq_process_var = 0.001;
105
110
115
120 double kalman_q_obs_var = 0.01;
121
126 double kalman_dq_obs_var = 0.1;
127
132 double kalman_q_d_obs_var = 0.0001;
133
138 double kalman_dq_d_obs_var = 0.0001;
139
144 double kalman_ddq_d_obs_var = 0.0001;
145
151 };
152
154 static constexpr size_t degrees_of_freedoms{7};
155
157 static constexpr double control_rate{0.001};
158
162 explicit Robot(const std::string &fci_hostname);
163
168 explicit Robot(const std::string &fci_hostname, const Params &params);
169
170 using franka::Robot::setCollisionBehavior;
171
180
196
224
230 bool recoverFromErrors();
231
236 [[nodiscard]] bool hasErrors();
237
243
249
255 auto s = state();
256 return {
257 {Affine(Eigen::Matrix4d::Map(s.O_T_EE.data())), ElbowState{s.elbow}}, RobotVelocity(s.O_dP_EE_c, s.delbow_c)};
258 }
259
265 auto s = state();
266 return {s.q, s.dq};
267 }
268
274
280
286
292
298
304
309 [[nodiscard]] bool is_in_control();
310
314 [[nodiscard]] std::string fci_hostname() const;
315
319 [[nodiscard]] std::optional<ControlSignalType> current_control_signal_type();
320
327 [[nodiscard]] std::shared_ptr<const Model> model() const { return model_; }
328
329#ifdef FRANKA_0_15
334 [[nodiscard]] std::string model_urdf() const { return model_urdf_; }
335#endif
336
341 bool joinMotion() {
342 std::unique_lock lock(*control_mutex_);
343 return joinMotionUnsafe(lock);
344 }
345
354 template <class Rep, class Period>
355 bool joinMotion(const std::chrono::duration<Rep, Period> &timeout) {
356 std::unique_lock lock(*control_mutex_);
358 }
359
366 [[nodiscard]]
367 bool pollMotion() {
368 return joinMotion(std::chrono::milliseconds(0));
369 }
370
371 // These helper functions are needed as the implicit template deduction does
372 // not work on subclasses of Motion
373
383 void move(
384 const std::shared_ptr<Motion<franka::CartesianPose>> &motion, bool async = false, bool limit_rate = false,
385 double cutoff_frequency = franka::kDefaultCutoffFrequency) {
387 motion,
388 [this, limit_rate, cutoff_frequency](const ControlFunc<franka::CartesianPose> &m) {
390 },
391 async);
392 }
393
403 void move(
404 const std::shared_ptr<Motion<franka::CartesianVelocities>> &motion, bool async = false, bool limit_rate = false,
405 double cutoff_frequency = franka::kDefaultCutoffFrequency) {
407 motion,
408 [this, limit_rate, cutoff_frequency](const ControlFunc<franka::CartesianVelocities> &m) {
410 },
411 async);
412 }
413
423 void move(
424 const std::shared_ptr<Motion<franka::JointPositions>> &motion, bool async = false, bool limit_rate = false,
425 double cutoff_frequency = franka::kDefaultCutoffFrequency) {
427 motion,
428 [this, limit_rate, cutoff_frequency](const ControlFunc<franka::JointPositions> &m) {
430 },
431 async);
432 }
433
443 void move(
444 const std::shared_ptr<Motion<franka::JointVelocities>> &motion, bool async = false, bool limit_rate = false,
445 double cutoff_frequency = franka::kDefaultCutoffFrequency) {
447 motion,
448 [this, limit_rate, cutoff_frequency](const ControlFunc<franka::JointVelocities> &m) {
450 },
451 async);
452 }
453
463 void move(
464 const std::shared_ptr<Motion<franka::Torques>> &motion, bool async = false, bool limit_rate = false,
465 double cutoff_frequency = franka::kDefaultCutoffFrequency) {
467 motion,
468 [this, limit_rate, cutoff_frequency](const ControlFunc<franka::Torques> &m) {
470 },
471 async);
472 }
473
474 private:
475 std::shared_ptr<const Model> model_;
476#ifdef FRANKA_0_15
477 std::string model_urdf_;
478#endif
479
480 template <typename ControlSignalType>
481 using ControlFunc = std::function<ControlSignalType(const franka::RobotState &, franka::Duration)>;
482 using MotionGeneratorVariant = std::variant<
486
488 std::string fci_hostname_;
489 Params params_;
490 // Written by the real-time thread while in control and by user threads (under
491 // control_mutex_) otherwise; control_mutex_ synchronizes the writer handover.
493 // Serializes user-side readers of state_buffer_. Never taken by the real-time thread.
494 std::mutex state_mutex_;
495 std::shared_ptr<std::mutex> control_mutex_;
496 std::condition_variable control_finished_condition_;
497 std::exception_ptr control_exception_;
498 std::thread control_thread_;
499 MotionGeneratorVariant motion_generator_{std::nullopt};
500 bool motion_generator_running_{false};
501 WaitFreeTripleBuffer<RelativeDynamicsFactor> relative_dynamics_factor_handle_;
502
503 [[nodiscard]] bool is_in_control_unsafe() const;
504
505 public:
506 // IMPORTANT: this has to come after control_mutex_ as otherwise
507 // control_mutex_ will be uninitialized when passed to the constructor of the
508 // DynamicsLimit class Limits provided by Franka for the FR3:
509 // https://frankaemika.github.io/docs/control_parameters.html
510 // clang-format off
515
520
525
530
535
540
545
550
555
560
565
570
571 // clang-format on
572
573 private:
574 template <class Rep = long, class Period = std::ratio<1>>
575 bool joinMotionUnsafe(
576 std::unique_lock<std::mutex> &lock,
577 const std::optional<std::chrono::duration<Rep, Period>> &timeout = std::nullopt) {
578 while (motion_generator_running_) {
579 if (timeout.has_value()) {
580 if (control_finished_condition_.wait_for(lock, timeout.value()) == std::cv_status::timeout) {
581 return false;
582 }
583 } else {
584 control_finished_condition_.wait(lock);
585 }
586 }
587 if (control_thread_.joinable()) control_thread_.join();
588 if (control_exception_ != nullptr) {
589 auto control_exception = control_exception_;
590 control_exception_ = nullptr;
591 std::rethrow_exception(control_exception);
592 }
593 return true;
594 }
595
596 template <typename ControlSignalType>
597 void moveInternal(
598 const std::shared_ptr<Motion<ControlSignalType>> &motion,
599 const std::function<void(const ControlFunc<ControlSignalType> &)> &control_func_executor, bool async) {
600 if (motion == nullptr) {
601 throw std::invalid_argument("The motion must not be null.");
602 }
603 // Fail-fast check in the user thread; the authoritative lock-free check is in Motion::init.
604 if (motion->has_started()) {
605 throw MotionReuseException(
606 "This motion object has already been started before. Motions cannot be reused; create a new motion "
607 "instance instead.");
608 }
609 { // Do not remove brace, it is needed to scope the lock
610 std::unique_lock lock(*control_mutex_);
611 if (is_in_control_unsafe() && motion_generator_running_) {
612 if (!std::holds_alternative<MotionGenerator<ControlSignalType>>(motion_generator_)) {
613 throw InvalidMotionTypeException(
614 "The type of motion cannot change during runtime. Please ensure "
615 "that the "
616 "previous motion finished before using a new type of motion.");
617 }
618 std::get<MotionGenerator<ControlSignalType>>(motion_generator_).updateMotion(motion);
619 } else {
620 joinMotionUnsafe(lock);
621
622 motion_generator_.emplace<MotionGenerator<ControlSignalType>>(this, motion);
623 auto motion_generator = &std::get<MotionGenerator<ControlSignalType>>(motion_generator_);
624 motion_generator->registerUpdateCallback(
625 [this](const RobotState &robot_state, franka::Duration duration, franka::Duration time) {
626 state_buffer_.set(robot_state);
627 });
628 motion_generator_running_ = true;
629 control_thread_ = std::thread([this, control_func_executor, motion_generator]() {
630 try {
631 bool done = false;
632 RobotStateEstimator robot_state_estimator(
633 params_.kalman_q_process_var,
634 params_.kalman_dq_process_var,
635 params_.kalman_ddq_process_var,
636 params_.kalman_control_process_var,
637 params_.kalman_q_obs_var,
638 params_.kalman_dq_obs_var,
639 params_.kalman_q_d_obs_var,
640 params_.kalman_dq_d_obs_var,
641 params_.kalman_ddq_d_obs_var,
642 params_.kalman_control_adaptation_rate);
643 while (!done) {
645 [this, motion_generator, &robot_state_estimator](const franka::RobotState &rs, franka::Duration d) {
646 return (*motion_generator)(robot_state_estimator.update(rs, *model_), d);
647 });
648 std::unique_lock lock(*control_mutex_);
649
650 // This code is just for the case that a new motion is set just
651 // after the old one terminates. If this happens, we need to
652 // continue with this motion, unless an exception occurs.
653 done = !motion_generator->has_new_motion();
654 if (motion_generator->has_new_motion()) {
655 motion_generator->resetTimeUnsafe();
656 } else {
657 done = true;
658 motion_generator_running_ = false;
659 control_finished_condition_.notify_all();
660 }
661 }
662 } catch (...) {
663 std::unique_lock lock(*control_mutex_);
664 control_exception_ = std::current_exception();
665 motion_generator_running_ = false;
666 control_finished_condition_.notify_all();
667 }
668 });
669 }
670 }
671 if (!async) joinMotion();
672 }
673};
674
675} // namespace franky
Definition cartesian_state.hpp:17
RobotPose pose() const
Definition cartesian_state.hpp:62
RobotVelocity velocity() const
Definition cartesian_state.hpp:67
A template class representing a dynamics limit with a maximum value.
Definition dynamics_limit.hpp:23
Elbow state of the robot.
Definition elbow_state.hpp:24
Joint state of a robot.
Definition joint_state.hpp:16
Vector7d velocity() const
The velocity component of the state.
Definition joint_state.hpp:48
Vector7d position() const
The position component of the state.
Definition joint_state.hpp:43
Helper class for handling motions and reactions.
Definition motion_generator.hpp:31
Base class for motions.
Definition motion.hpp:25
Relative dynamics factors.
Definition relative_dynamics_factor.hpp:13
A class representing a Franka robot.
Definition robot.hpp:58
DynamicsLimit< Vector7d > joint_acceleration_limit
Joint acceleration limit [rad/s²].
Definition robot.hpp:564
bool joinMotion(const std::chrono::duration< Rep, Period > &timeout)
Wait for the current motion to finish with a timeout. Throw any exceptions that occurred during the m...
Definition robot.hpp:355
std::optional< ControlSignalType > current_control_signal_type()
The type of the current control signal.
Definition robot.cpp:112
std::string fci_hostname() const
The hostname of the robot.
Definition robot.cpp:110
void move(const std::shared_ptr< Motion< franka::CartesianPose > > &motion, bool async=false, bool limit_rate=false, double cutoff_frequency=franka::kDefaultCutoffFrequency)
Execute the given motion.
Definition robot.hpp:383
Vector7d currentJointVelocities()
Returns the current joint velocities of the robot.
Definition robot.hpp:279
bool joinMotion()
Wait for the current motion to finish. Throw any exceptions that occurred during the motion.
Definition robot.hpp:341
static constexpr double control_rate
Definition robot.hpp:157
DynamicsLimit< double > elbow_acceleration_limit
Elbow acceleration limit [rad/s²].
Definition robot.hpp:539
RelativeDynamicsFactor relative_dynamics_factor()
Returns the current global relative dynamics factor of the robot.
Definition robot.cpp:123
Vector7d currentJointPositions()
Returns the current joint positions of the robot.
Definition robot.hpp:273
CartesianState currentCartesianState()
Returns the current cartesian state of the robot.
Definition robot.hpp:254
DynamicsLimit< Vector7d > joint_velocity_limit
Joint velocity limit [rad/s].
Definition robot.hpp:559
RobotState state()
Returns the current state of the robot.
Definition robot.cpp:60
void move(const std::shared_ptr< Motion< franka::Torques > > &motion, bool async=false, bool limit_rate=false, double cutoff_frequency=franka::kDefaultCutoffFrequency)
Execute the given motion.
Definition robot.hpp:463
DynamicsLimit< double > translation_jerk_limit
Translational jerk limit [m/s³].
Definition robot.hpp:544
DynamicsLimit< double > translation_velocity_limit
Translational velocity limit [m/s].
Definition robot.hpp:514
bool recoverFromErrors()
Calls the automatic error recovery of the robot and returns whether the recovery was successful.
Definition robot.cpp:55
void move(const std::shared_ptr< Motion< franka::JointPositions > > &motion, bool async=false, bool limit_rate=false, double cutoff_frequency=franka::kDefaultCutoffFrequency)
Execute the given motion.
Definition robot.hpp:423
DynamicsLimit< double > elbow_velocity_limit
Elbow velocity limit [rad/s].
Definition robot.hpp:524
DynamicsLimit< double > rotation_velocity_limit
Rotational velocity limit [rad/s].
Definition robot.hpp:519
DynamicsLimit< double > elbow_jerk_limit
Elbow jerk limit [rad/s³].
Definition robot.hpp:554
bool is_in_control()
Whether the robot is currently in control, i.e. a motion is being executed.
Definition robot.cpp:105
void move(const std::shared_ptr< Motion< franka::CartesianVelocities > > &motion, bool async=false, bool limit_rate=false, double cutoff_frequency=franka::kDefaultCutoffFrequency)
Execute the given motion.
Definition robot.hpp:403
DynamicsLimit< Vector7d > joint_jerk_limit
Joint jerk limit [rad/s³].
Definition robot.hpp:569
JointState currentJointState()
Returns the current joint state of the robot.
Definition robot.hpp:264
void setCollisionBehavior(const ScalarOrArray< 7 > &torque_threshold, const ScalarOrArray< 6 > &force_threshold)
Set the collision behavior of the robot.
Definition robot.cpp:72
static constexpr size_t degrees_of_freedoms
Definition robot.hpp:154
RobotVelocity currentCartesianVelocity()
Returns the current cartesian velocity of the robot.
Definition robot.hpp:248
DynamicsLimit< double > rotation_jerk_limit
Rotational jerk limit [rad/s³].
Definition robot.hpp:549
void setRelativeDynamicsFactor(const RelativeDynamicsFactor &relative_dynamics_factor)
Sets the global relative dynamics factor of the robot.
Definition robot.cpp:127
std::shared_ptr< const Model > model() const
The model of the robot.
Definition robot.hpp:327
DynamicsLimit< double > translation_acceleration_limit
Translational acceleration limit [m/s²].
Definition robot.hpp:529
bool hasErrors()
Returns whether the robot has errors.
Definition robot.cpp:53
RobotPose currentPose()
Returns the current pose of the robot.
Definition robot.hpp:242
DynamicsLimit< double > rotation_acceleration_limit
Rotational acceleration limit [rad/s²].
Definition robot.hpp:534
RelativeDynamicsFactor relative_dynamics_factor_rt()
Returns the current global relative dynamics factor of the robot (Real-Time safe).
Definition robot.cpp:125
void move(const std::shared_ptr< Motion< franka::JointVelocities > > &motion, bool async=false, bool limit_rate=false, double cutoff_frequency=franka::kDefaultCutoffFrequency)
Execute the given motion.
Definition robot.hpp:443
bool pollMotion()
Check whether the robot is still in motion. This function is non-blocking and returns immediately....
Definition robot.hpp:367
Cartesian pose of a robot.
Definition robot_pose.hpp:19
Cartesian velocity of a robot.
Definition robot_velocity.hpp:20
Wait-free, Single-Producer Single-Consumer (SPSC) triple buffer.
Definition wait_free_triple_buffer.hpp:17
void set(const T &value)
Publish new data.
Definition wait_free_triple_buffer.hpp:26
Definition dynamics_limit.cpp:8
std::array< double, dims > toStdD(const Eigen::Matrix< double, dims, 1 > &vector)
Definition util.hpp:18
Eigen::Vector< double, 7 > Vector7d
Definition types.hpp:11
ControlSignalType
Type of control signal.
Definition control_signal_type.hpp:8
std::variant< double, Array< dims > > ScalarOrArray
Definition types.hpp:22
Eigen::Affine3d Affine
Definition types.hpp:16
Exception thrown when an invalid motion type is used.
Definition robot.hpp:38
Exception thrown when a motion is started more than once.
Definition robot.hpp:48
Global parameters for the robot.
Definition robot.hpp:63
double kalman_dq_process_var
Kalman parameter: process noise variance of the velocity.
Definition robot.hpp:104
RelativeDynamicsFactor relative_dynamics_factor
Relative dynamics factor for the robot.
Definition robot.hpp:70
double default_force_threshold
Default force threshold for collision behavior.
Definition robot.hpp:80
double kalman_control_adaptation_rate
Kalman parameter: rate of adaptation of the robot state to the desired robot state.
Definition robot.hpp:150
double kalman_dq_obs_var
Kalman parameter: observation noise variance of measured joint velocities.
Definition robot.hpp:126
double kalman_q_obs_var
Kalman parameter: observation noise variance of measured joint positions.
Definition robot.hpp:120
double kalman_dq_d_obs_var
Kalman parameter: observation noise variance of desired joint velocities.
Definition robot.hpp:138
franka::ControllerMode controller_mode
Default controller mode for the robot.
Definition robot.hpp:87
double kalman_control_process_var
Kalman parameter: process noise variance of the control signal.
Definition robot.hpp:114
double kalman_q_d_obs_var
Kalman parameter: observation noise variance of desired joint positions.
Definition robot.hpp:132
franka::RealtimeConfig realtime_config
Default realtime configuration for the robot.
Definition robot.hpp:94
double kalman_ddq_d_obs_var
Kalman parameter: observation noise variance of desired joint accelerations.
Definition robot.hpp:144
double default_torque_threshold
Default torque threshold for collision behavior.
Definition robot.hpp:75
double kalman_ddq_process_var
Kalman parameter: process noise variance of the acceleration.
Definition robot.hpp:109
double kalman_q_process_var
Kalman parameter: process noise variance of the position.
Definition robot.hpp:99
Full state of the robot.
Definition robot_state.hpp:40