cartesian_trajectory_segment.cpp
Go to the documentation of this file.
1 // -- BEGIN LICENSE BLOCK ----------------------------------------------
2 // Copyright 2021 FZI Forschungszentrum Informatik
3 // Created on behalf of Universal Robots A/S
4 //
5 // Licensed under the Apache License, Version 2.0 (the "License");
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 //
9 // http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 // -- END LICENSE BLOCK ------------------------------------------------
17 
18 //-----------------------------------------------------------------------------
25 //-----------------------------------------------------------------------------
26 
28 #include <algorithm>
29 #include <cmath>
30 #include "Eigen/src/Core/GlobalFunctions.h"
31 #include "Eigen/src/Core/Matrix.h"
32 #include "Eigen/src/Core/util/Constants.h"
33 #include "Eigen/src/Geometry/Quaternion.h"
34 #include <Eigen/Dense>
35 
37 {
40 
42  const Time& end_time, const CartesianState& end_state)
43  : QuinticSplineSegment(start_time, convert(start_state), end_time, convert(end_state)){};
44 
46 {
47  // Sample from the underlying spline segment.
48  SplineState s(7);
50 
51  if (time < this->startTime() || time > this->endTime())
52  {
53  state.p = Eigen::Vector3d(s.position[0], s.position[1], s.position[2]);
54  state.q = Eigen::Quaterniond(s.position[3], s.position[4], s.position[5], s.position[6]).normalized();
55 
56  state.v = Eigen::Vector3d::Zero();
57  state.w = Eigen::Vector3d::Zero();
58  state.v_dot = Eigen::Vector3d::Zero();
59  state.w_dot = Eigen::Vector3d::Zero();
60  }
61  else
62  {
63  state = convert(s);
64  }
65 }
66 
68 {
69  SplineState spline_state;
70 
71  // Note: The pre-multiplication of velocity and acceleration terms with
72  // `state.q.inverse()` transforms them into the body-local reference frame.
73  // This is required for computing quaternion-based velocities and
74  // accelerations below.
75 
76  // Convenience method
77  auto fill = [](auto& vec, const auto& first, const auto& second) {
78  vec.push_back(first.x());
79  vec.push_back(first.y());
80  vec.push_back(first.z());
81 
82  vec.push_back(second.w());
83  vec.push_back(second.x());
84  vec.push_back(second.y());
85  vec.push_back(second.z());
86  };
87 
88  // Spline positions
89  fill(spline_state.position, state.p, state.q);
90 
91  // Spline velocities
92  if (std::isnan(state.v.x()) || std::isnan(state.v.y()) || std::isnan(state.v.z()) || std::isnan(state.w.x()) ||
93  std::isnan(state.w.y()) || std::isnan(state.w.z()))
94  {
95  return spline_state; // with uninitialized velocity/acceleration data
96  }
97  Eigen::Quaterniond q_dot;
98  Eigen::Vector3d tmp = state.q.inverse() * state.w;
99  Eigen::Quaterniond omega(0, tmp.x(), tmp.y(), tmp.z());
100  q_dot.coeffs() = 0.5 * (omega * state.q).coeffs();
101 
102  fill(spline_state.velocity, state.q.inverse() * state.v, q_dot);
103 
104  // Spline accelerations
105  if (std::isnan(state.v_dot.x()) || std::isnan(state.v_dot.y()) || std::isnan(state.v_dot.z()) ||
106  std::isnan(state.w_dot.x()) || std::isnan(state.w_dot.y()) || std::isnan(state.w_dot.z()))
107  {
108  return spline_state; // with uninitialized acceleration data
109  }
110  Eigen::Quaterniond q_ddot;
111  tmp = state.q.inverse() * state.w_dot;
112  Eigen::Quaterniond omega_dot(0, tmp.x(), tmp.y(), tmp.z());
113  q_ddot.coeffs() = 0.5 * (omega_dot * state.q).coeffs() + 0.5 * (omega * q_dot).coeffs();
114 
115  fill(spline_state.acceleration, state.q.inverse() * state.v_dot, q_ddot);
116 
117  return spline_state;
118 };
119 
121 {
122  CartesianState state;
123 
124  // Cartesian positions
125  if (s.position.empty())
126  {
127  return state; // with positions/velocities/accelerations zero initialized
128  }
129  state.p = Eigen::Vector3d(s.position[0], s.position[1], s.position[2]);
130  state.q = Eigen::Quaterniond(s.position[3], s.position[4], s.position[5], s.position[6]).normalized();
131 
132  // Cartesian velocities
133  if (s.velocity.empty())
134  {
135  return state; // with velocities/accelerations zero initialized
136  }
137  Eigen::Quaterniond q_dot(s.velocity[3], s.velocity[4], s.velocity[5], s.velocity[6]);
138 
139  Eigen::Quaterniond omega;
140  omega.coeffs() = 2.0 * (q_dot * state.q.inverse()).coeffs();
141 
142  state.v = Eigen::Vector3d(s.velocity[0], s.velocity[1], s.velocity[2]);
143  state.w = Eigen::Vector3d(omega.x(), omega.y(), omega.z());
144 
145  // Cartesian accelerations
146  if (s.acceleration.empty())
147  {
148  return state; // with accelerations zero initialized
149  }
150  Eigen::Quaterniond q_ddot(s.acceleration[3], s.acceleration[4], s.acceleration[5], s.acceleration[6]);
151 
152  Eigen::Quaterniond omega_dot;
153  omega_dot.coeffs() = 2.0 * ((q_ddot * state.q.inverse()).coeffs() -
154  ((q_dot * state.q.inverse()) * (q_dot * state.q.inverse())).coeffs());
155 
156  state.v_dot = Eigen::Vector3d(s.acceleration[0], s.acceleration[1], s.acceleration[2]);
157  state.w_dot = Eigen::Vector3d(omega_dot.x(), omega_dot.y(), omega_dot.z());
158 
159  // Re-transform vel and acc to the correct reference frame.
160  state.v = state.q * state.v;
161  state.w = state.q * state.w;
162  state.v_dot = state.q * state.v_dot;
163  state.w_dot = state.q * state.w_dot;
164 
165  return state;
166 }
167 
168 std::ostream& operator<<(std::ostream& out, const CartesianTrajectorySegment::SplineState& state)
169 {
170  out << "pos:\n";
171  for (size_t i = 0; i < state.position.size(); ++i)
172  {
173  out << state.position[i] << '\n';
174  }
175  out << "vel:\n";
176  for (size_t i = 0; i < state.velocity.size(); ++i)
177  {
178  out << state.velocity[i] << '\n';
179  }
180  out << "acc:\n";
181  for (size_t i = 0; i < state.acceleration.size(); ++i)
182  {
183  out << state.acceleration[i] << '\n';
184  }
185 
186  return out;
187 }
188 } // namespace ros_controllers_cartesian
std::vector< Scalar > acceleration
Eigen::Vector3d w
angular velocity,
void sample(const Time &time, State &state) const
XmlRpcServer s
QuinticSplineSegment::Time Time
Relative time in seconds.
void sample(const Time &time, CartesianState &state) const
Sample the CartesianState at the given time.
CartesianTrajectorySegment::Time Time
Eigen::Vector3d v
linear velocity,
QuinticSplineSegment::State SplineState
State of a 7-dimensional Spline.
std::ostream & operator<<(std::ostream &os, const CartesianTrajectorySegment::SplineState &state)
Stream operator for testing and debugging.
CartesianTrajectorySegment::SplineState convert(const CartesianState &state)
Convert a CartesianState into a ros_controllers_cartesian::SplineState.
Eigen::Vector3d v_dot
linear acceleration,
Cartesian state with pose, velocity and acceleration.
Eigen::Vector3d w_dot
angular acceleration,


cartesian_trajectory_interpolation
Author(s):
autogenerated on Thu Feb 23 2023 03:10:46