Franky  0.9.1
A High-Level Motion API for Franka
waypoint_motion.hpp
Go to the documentation of this file.
1 #pragma once
2 
3 #include <atomic>
4 #include <optional>
5 #include <ruckig/ruckig.hpp>
6 
7 #include "franky/util.hpp"
11 
12 namespace franky {
13 
17 struct MotionPlannerException : public std::runtime_error {
18  using std::runtime_error::runtime_error;
19 };
20 
33 template<typename TargetType>
34 struct Waypoint {
35  TargetType target;
36 
38 
40 
41  std::optional<double> minimum_time{std::nullopt};
42 };
43 
50 template<typename ControlSignalType, typename TargetType>
51 class WaypointMotion : public Motion<ControlSignalType> {
52  public:
56  struct Params {
62 
67  };
68 
73  explicit WaypointMotion(std::vector<Waypoint<TargetType>> waypoints, Params params)
74  : waypoints_(std::move(waypoints)), params_(std::move(params)), prev_result_() {}
75 
76  protected:
77  void initImpl(const franka::RobotState &robot_state,
78  const std::optional<ControlSignalType> &previous_command) override {
79  current_cooldown_iteration_ = 0;
80 
81  initWaypointMotion(robot_state, previous_command, input_para_);
82 
83  waypoint_iterator_ = waypoints_.begin();
84  if (waypoint_iterator_ != waypoints_.end()) {
85  setNewWaypoint(robot_state, previous_command, *waypoint_iterator_, input_para_);
86  setInputLimits(*waypoint_iterator_);
87  prev_result_ = ruckig::Result::Working;
88  } else {
89  prev_result_ = ruckig::Result::Finished;
90  }
91  }
92 
95  const franka::RobotState &robot_state,
96  franka::Duration time_step,
97  double rel_time,
98  double abs_time,
99  const std::optional<ControlSignalType> &previous_command) override {
100  const uint64_t steps = std::max<uint64_t>(time_step.toMSec(), 1);
101  for (size_t i = 0; i < steps; i++) {
102  if (prev_result_ == ruckig::Result::Finished) {
103  if (waypoint_iterator_ != waypoints_.end())
104  ++waypoint_iterator_;
105  if (waypoint_iterator_ == waypoints_.end()) {
106  auto output_pose = getControlSignal(input_para_);
107  // Allow cooldown of motion, so that the low-pass filter has time to adjust to target values
108  if (!params_.return_when_finished) {
109  return output_pose;
110  } else if (current_cooldown_iteration_ < cooldown_iterations_) {
111  current_cooldown_iteration_ += 1;
112  return output_pose;
113  }
114  return franka::MotionFinished(output_pose);
115  } else {
116  setNewWaypoint(robot_state, previous_command, *waypoint_iterator_, input_para_);
117  setInputLimits(*waypoint_iterator_);
118  }
119  }
120  if (waypoint_iterator_ != waypoints_.end()) {
121  prev_result_ = trajectory_generator_.update(input_para_, output_para_);
122  if (prev_result_ == ruckig::Result::Error) {
123  throw MotionPlannerException("Invalid inputs to motion planner.");
124  }
125  output_para_.pass_to_input(input_para_);
126  }
127  }
128 
129  return getControlSignal(input_para_);
130  };
131 
132  virtual void initWaypointMotion(
133  const franka::RobotState &robot_state,
134  const std::optional<ControlSignalType> &previous_command,
135  ruckig::InputParameter<7> &input_parameter) = 0;
136 
137  virtual void setNewWaypoint(
138  const franka::RobotState &robot_state,
139  const std::optional<ControlSignalType> &previous_command,
140  const Waypoint<TargetType> &new_waypoint,
141  ruckig::InputParameter<7> &input_parameter) = 0;
142 
143  [[nodiscard]] virtual std::tuple<Vector7d, Vector7d, Vector7d> getAbsoluteInputLimits() const = 0;
144 
145  [[nodiscard]] virtual ControlSignalType getControlSignal(const ruckig::InputParameter<7> &input_parameter) const = 0;
146 
147  private:
148  std::vector<Waypoint<TargetType>> waypoints_;
149  Params params_;
150 
151  ruckig::Ruckig<7> trajectory_generator_{Robot::control_rate};
152  ruckig::Result prev_result_;
153  ruckig::InputParameter<7> input_para_;
154  ruckig::OutputParameter<7> output_para_;
155 
156  typename std::vector<Waypoint<TargetType>>::iterator waypoint_iterator_;
157 
158  constexpr static size_t cooldown_iterations_{5};
159  size_t current_cooldown_iteration_{0};
160 
161  void setInputLimits(const Waypoint<TargetType> &waypoint) {
162  auto robot = this->robot();
163 
164  auto [vel_lim, acc_lim, jerk_lim] = getAbsoluteInputLimits();
165 
166  auto relative_dynamics_factor =
167  waypoint.relative_dynamics_factor * params_.relative_dynamics_factor * robot->relative_dynamics_factor();
168 
169  input_para_.max_velocity = toStd<7>(relative_dynamics_factor.velocity() * vel_lim);
170  input_para_.max_acceleration = toStd<7>(relative_dynamics_factor.acceleration() * acc_lim);
171  input_para_.max_jerk = toStd<7>(relative_dynamics_factor.jerk() * jerk_lim);
172 
173  if (relative_dynamics_factor.max_dynamics()) {
174  input_para_.synchronization = ruckig::Synchronization::TimeIfNecessary;
175  } else {
176  input_para_.synchronization = ruckig::Synchronization::Time;
177  if (waypoint.minimum_time.has_value())
178  input_para_.minimum_duration = waypoint.minimum_time.value();
179  }
180  }
181 };
182 
183 } // namespace franky
Base class for motions.
Definition: motion.hpp:22
Robot * robot() const
Definition: motion.hpp:105
Relative dynamics factors.
Definition: relative_dynamics_factor.hpp:13
static constexpr double control_rate
Definition: robot.hpp:148
RelativeDynamicsFactor relative_dynamics_factor()
Returns the current global relative dynamics factor of the robot.
Definition: robot.cpp:145
A motion following multiple waypoints in a time-optimal way. Works with arbitrary initial conditions.
Definition: waypoint_motion.hpp:51
ControlSignalType nextCommandImpl(const franka::RobotState &robot_state, franka::Duration time_step, double rel_time, double abs_time, const std::optional< ControlSignalType > &previous_command) override
Definition: waypoint_motion.hpp:94
void initImpl(const franka::RobotState &robot_state, const std::optional< ControlSignalType > &previous_command) override
Definition: waypoint_motion.hpp:77
WaypointMotion(std::vector< Waypoint< TargetType >> waypoints, Params params)
Definition: waypoint_motion.hpp:73
virtual std::tuple< Vector7d, Vector7d, Vector7d > getAbsoluteInputLimits() const =0
virtual void initWaypointMotion(const franka::RobotState &robot_state, const std::optional< ControlSignalType > &previous_command, ruckig::InputParameter< 7 > &input_parameter)=0
virtual ControlSignalType getControlSignal(const ruckig::InputParameter< 7 > &input_parameter) const =0
virtual void setNewWaypoint(const franka::RobotState &robot_state, const std::optional< ControlSignalType > &previous_command, const Waypoint< TargetType > &new_waypoint, ruckig::InputParameter< 7 > &input_parameter)=0
Definition: gripper.cpp:3
ReferenceType
Enum class for reference types.
Definition: reference_type.hpp:10
ControlSignalType
Type of control signal.
Definition: control_signal_type.hpp:8
Exception thrown if the motion planner fails.
Definition: waypoint_motion.hpp:17
A waypoint with a target and optional parameters.
Definition: waypoint_motion.hpp:34
TargetType target
Definition: waypoint_motion.hpp:35
RelativeDynamicsFactor relative_dynamics_factor
Definition: waypoint_motion.hpp:39
std::optional< double > minimum_time
Definition: waypoint_motion.hpp:41
ReferenceType reference_type
Definition: waypoint_motion.hpp:37
Parameters for the waypoint motion.
Definition: waypoint_motion.hpp:56
RelativeDynamicsFactor relative_dynamics_factor
Definition: waypoint_motion.hpp:61
bool return_when_finished
Definition: waypoint_motion.hpp:66