trajectory.cpp
Go to the documentation of this file.
1 
9 /*
10  * Copyright 2018 Martina Rivizzigno.
11  *
12  * This file is part of the mavros package and subject to the license terms
13  * in the top-level LICENSE file of the mavros repository.
14  * https://github.com/mavlink/mavros/tree/master/LICENSE.mdA
15  */
16 
17 #include <mavros/mavros_plugin.h>
18 #include <mavros_msgs/Trajectory.h>
19 #include <mavros_msgs/PositionTarget.h>
20 #include <nav_msgs/Path.h>
21 
22 namespace mavros {
23 namespace extra_plugins {
24 using utils::enum_value;
25 
27 static constexpr size_t NUM_POINTS = 5;
28 
30 using MavPoints = std::array<float, NUM_POINTS>;
31 
32 using RosPoints = mavros_msgs::PositionTarget;
33 
41 public:
43  trajectory_nh("~trajectory")
44  { }
45 
46  void initialize(UAS &uas_) override
47  {
49 
52  trajectory_desired_pub = trajectory_nh.advertise<mavros_msgs::Trajectory>("desired", 10);
53  }
54 
56  {
57  return {
59  };
60  }
61 
62 private:
64 
67 
69 
70  // [[[cog:
71  // def outl_fill_points_ned_vector(x, y, z, vec_name, vec_type, point_xyz):
72  // cog.outl(
73  // """void fill_points_{vec_name}(MavPoints &{x}, MavPoints &{y}, MavPoints &{z}, const geometry_msgs::{vec_type} &{vec_name}, const size_t i)\n"""
74  // """{{\n"""
75  // """\tauto {vec_name}_ned = ftf::transform_frame_enu_ned(ftf::to_eigen({vec_name}));\n"""
76  // .format(**locals())
77  // )
78  //
79  // for axis in "xyz":
80  // cog.outl("\t{axis}[i] = {vec_name}_ned.{axis}();".format(**locals()))
81  //
82  // cog.outl("}\n")
83  //
84  //
85  // outl_fill_points_ned_vector('x', 'y', 'z', 'position', 'Point', range(0, 3))
86  // outl_fill_points_ned_vector('x', 'y', 'z', 'velocity', 'Vector3', range(3, 6))
87  // outl_fill_points_ned_vector('x', 'y', 'z', 'acceleration', 'Vector3', range(6, 9))
88  // ]]]
89  void fill_points_position(MavPoints &x, MavPoints &y, MavPoints &z, const geometry_msgs::Point &position, const size_t i)
90  {
91  auto position_ned = ftf::transform_frame_enu_ned(ftf::to_eigen(position));
92 
93  x[i] = position_ned.x();
94  y[i] = position_ned.y();
95  z[i] = position_ned.z();
96  }
97 
98  void fill_points_velocity(MavPoints &x, MavPoints &y, MavPoints &z, const geometry_msgs::Vector3 &velocity, const size_t i)
99  {
100  auto velocity_ned = ftf::transform_frame_enu_ned(ftf::to_eigen(velocity));
101 
102  x[i] = velocity_ned.x();
103  y[i] = velocity_ned.y();
104  z[i] = velocity_ned.z();
105  }
106 
107  void fill_points_acceleration(MavPoints &x, MavPoints &y, MavPoints &z, const geometry_msgs::Vector3 &acceleration, const size_t i)
108  {
109  auto acceleration_ned = ftf::transform_frame_enu_ned(ftf::to_eigen(acceleration));
110 
111  x[i] = acceleration_ned.x();
112  y[i] = acceleration_ned.y();
113  z[i] = acceleration_ned.z();
114  }
115 
116  // [[[end]]] (checksum: 92ea0f7f329c90c486fdb8b738c0e7c3)
117 
118 
119  void fill_points_yaw_wp(MavPoints &y, const double yaw, const size_t i) {
120  y[i] = wrap_pi(-yaw + (M_PI / 2.0f));
121  }
122 
123  void fill_points_yaw_speed(MavPoints &yv, const double yaw_speed, const size_t i) {
124  yv[i] = yaw_speed;
125  }
126 
127  void fill_points_yaw_q(MavPoints &y, const geometry_msgs::Quaternion &orientation, const size_t i) {
130  ftf::to_eigen(orientation)));
131  auto yaw_wp = ftf::quaternion_get_yaw(q_wp);
132 
133  y[i] = wrap_pi(-yaw_wp + (M_PI / 2.0f));
134  }
135 
136  void fill_points_delta(MavPoints &y, const double time_horizon, const size_t i) {
137  y[i] = time_horizon;
138  }
139 
140  auto fill_points_unused_path(mavlink::common::msg::TRAJECTORY_REPRESENTATION_WAYPOINTS & t, const size_t i) {
141  t.vel_x[i] = NAN;
142  t.vel_y[i] = NAN;
143  t.vel_z[i] = NAN;
144  t.acc_x[i] = NAN;
145  t.acc_y[i] = NAN;
146  t.acc_z[i] = NAN;
147  t.vel_yaw[i] = NAN;
148  }
149 
150  void fill_points_all_unused(mavlink::common::msg::TRAJECTORY_REPRESENTATION_WAYPOINTS &t, const size_t i) {
151  t.pos_x[i] = NAN;
152  t.pos_y[i] = NAN;
153  t.pos_z[i] = NAN;
154 
155  t.vel_x[i] = NAN;
156  t.vel_y[i] = NAN;
157  t.vel_z[i] = NAN;
158 
159  t.acc_x[i] = NAN;
160  t.acc_y[i] = NAN;
161  t.acc_z[i] = NAN;
162 
163  t.pos_yaw[i] = NAN;
164  t.vel_yaw[i] = NAN;
165  }
166 
167  void fill_points_all_unused_bezier(mavlink::common::msg::TRAJECTORY_REPRESENTATION_BEZIER &t, const size_t i) {
168  t.pos_x[i] = NAN;
169  t.pos_y[i] = NAN;
170  t.pos_z[i] = NAN;
171 
172  t.pos_yaw[i] = NAN;
173 
174  t.delta[i] = NAN;
175  }
176 
177  void fill_msg_position(geometry_msgs::Point &position, const mavlink::common::msg::TRAJECTORY_REPRESENTATION_WAYPOINTS &t, const size_t i)
178  {
179  auto position_enu = ftf::transform_frame_ned_enu(Eigen::Vector3d(t.pos_x[i], t.pos_y[i], t.pos_z[i]));
180 
181  position.x = position_enu.x();
182  position.y = position_enu.y();
183  position.z = position_enu.z();
184  }
185 
186  void fill_msg_velocity(geometry_msgs::Vector3 &velocity, const mavlink::common::msg::TRAJECTORY_REPRESENTATION_WAYPOINTS &t, const size_t i)
187  {
188  auto velocity_enu = ftf::transform_frame_ned_enu(Eigen::Vector3d(t.vel_x[i], t.vel_y[i], t.vel_z[i]));
189 
190  velocity.x = velocity_enu.x();
191  velocity.y = velocity_enu.y();
192  velocity.z = velocity_enu.z();
193  }
194 
195  void fill_msg_acceleration(geometry_msgs::Vector3 &acceleration, const mavlink::common::msg::TRAJECTORY_REPRESENTATION_WAYPOINTS &t, const size_t i)
196  {
197  auto acceleration_enu = ftf::transform_frame_ned_enu(Eigen::Vector3d(t.acc_x[i], t.acc_y[i], t.acc_z[i]));
198 
199  acceleration.x = acceleration_enu.x();
200  acceleration.y = acceleration_enu.y();
201  acceleration.z = acceleration_enu.z();
202  }
203 
204 
205  // -*- callbacks -*-
206 
214  {
215  ROS_ASSERT(NUM_POINTS == req->point_valid.size());
216 
217  if (req->type == mavros_msgs::Trajectory::MAV_TRAJECTORY_REPRESENTATION_WAYPOINTS) {
218  mavlink::common::msg::TRAJECTORY_REPRESENTATION_WAYPOINTS trajectory {};
219 
220  auto fill_point_rep_waypoints = [&](mavlink::common::msg::TRAJECTORY_REPRESENTATION_WAYPOINTS & t, const RosPoints &rp, const size_t i) {
221  const auto valid = req->point_valid[i];
222 
223  auto valid_so_far = trajectory.valid_points;
224  if (!valid) {
226  return;
227  }
228 
229  trajectory.valid_points = valid_so_far + 1;
230  fill_points_position(t.pos_x, t.pos_y, t.pos_z, rp.position, i);
231  fill_points_velocity(t.vel_x, t.vel_y, t.vel_z, rp.velocity, i);
232  fill_points_acceleration(t.acc_x, t.acc_y, t.acc_z, rp.acceleration_or_force, i);
233  fill_points_yaw_wp(t.pos_yaw, rp.yaw, i);
234  fill_points_yaw_speed(t.vel_yaw, rp.yaw_rate, i);
235  t.command[i] = UINT16_MAX;
236  };
237 
238  // [[[cog:
239  // for i in range(5):
240  // cog.outl(
241  // 'fill_point_rep_waypoints(trajectory, req->point_{i1}, {i0});'
242  // .format(i0=i, i1=i+1)
243  // )
244  // ]]]
245  fill_point_rep_waypoints(trajectory, req->point_1, 0);
246  fill_point_rep_waypoints(trajectory, req->point_2, 1);
247  fill_point_rep_waypoints(trajectory, req->point_3, 2);
248  fill_point_rep_waypoints(trajectory, req->point_4, 3);
249  fill_point_rep_waypoints(trajectory, req->point_5, 4);
250  // [[[end]]] (checksum: e993aeb535c2df6f07bf7b4f1fcf3d2e)
251 
252  trajectory.time_usec = req->header.stamp.toNSec() / 1000;
253  UAS_FCU(m_uas)->send_message_ignore_drop(trajectory);
254  } else {
255  mavlink::common::msg::TRAJECTORY_REPRESENTATION_BEZIER trajectory {};
256  auto fill_point_rep_bezier = [&](mavlink::common::msg::TRAJECTORY_REPRESENTATION_BEZIER & t, const RosPoints &rp, const size_t i) {
257  const auto valid = req->point_valid[i];
258 
259  auto valid_so_far = trajectory.valid_points;
260  if (!valid) {
262  return;
263  }
264 
265  trajectory.valid_points = valid_so_far + 1;
266  fill_points_position(t.pos_x, t.pos_y, t.pos_z, rp.position, i);
267  fill_points_yaw_wp(t.pos_yaw, rp.yaw, i);
268  fill_points_delta(t.delta, req->time_horizon[i], i);
269  };
270  // [[[cog:
271  // for i in range(5):
272  // cog.outl(
273  // 'fill_point_rep_bezier(trajectory, req->point_{i1}, {i0});'
274  // .format(i0=i, i1=i+1)
275  // )
276  // ]]]
277  fill_point_rep_bezier(trajectory, req->point_1, 0);
278  fill_point_rep_bezier(trajectory, req->point_2, 1);
279  fill_point_rep_bezier(trajectory, req->point_3, 2);
280  fill_point_rep_bezier(trajectory, req->point_4, 3);
281  fill_point_rep_bezier(trajectory, req->point_5, 4);
282  // [[[end]]] (checksum: 3e6da5f06e0b33682c6122c40f05c1f6)
283 
284  trajectory.time_usec = req->header.stamp.toNSec() / 1000;
285  UAS_FCU(m_uas)->send_message_ignore_drop(trajectory);
286  }
287 
288 
289  }
290 
291 
299  {
300  mavlink::common::msg::TRAJECTORY_REPRESENTATION_WAYPOINTS trajectory {};
301 
302  trajectory.time_usec = req->header.stamp.toNSec() / 1000;
303  trajectory.valid_points = std::min(NUM_POINTS, req->poses.size());
304 
305  auto fill_point = [&](mavlink::common::msg::TRAJECTORY_REPRESENTATION_WAYPOINTS & t, const size_t i) {
306  t.command[i] = UINT16_MAX;
307  if (req->poses.size() < i + 1) {
309  }
310  else {
311  auto &pose = req->poses[i].pose;
312 
313  fill_points_position(t.pos_x, t.pos_y, t.pos_z, pose.position, i);
314  fill_points_yaw_q(t.pos_yaw, pose.orientation, i);
316  }
317  };
318 
319  // [[[cog:
320  // for i in range(5):
321  // cog.outl(
322  // 'fill_point(trajectory, {i0});'.format(i0=i, i1=i+1))
323  // ]]]
324  fill_point(trajectory, 0);
325  fill_point(trajectory, 1);
326  fill_point(trajectory, 2);
327  fill_point(trajectory, 3);
328  fill_point(trajectory, 4);
329  // [[[end]]] (checksum: 267a911c65a3768f04a8230fcb235bca)
330 
331  UAS_FCU(m_uas)->send_message_ignore_drop(trajectory);
332  }
333 
334  void handle_trajectory(const mavlink::mavlink_message_t *msg, mavlink::common::msg::TRAJECTORY_REPRESENTATION_WAYPOINTS &trajectory)
335  {
336  auto tr_desired = boost::make_shared<mavros_msgs::Trajectory>();
337 
338  auto fill_msg_point = [&](RosPoints & p, const mavlink::common::msg::TRAJECTORY_REPRESENTATION_WAYPOINTS & t, const size_t i) {
339  fill_msg_position(p.position, t, i);
340  fill_msg_velocity(p.velocity, t, i);
341  fill_msg_acceleration(p.acceleration_or_force, t, i);
342  p.yaw = wrap_pi((M_PI / 2.0f) - t.pos_yaw[i]);
343  p.yaw_rate = t.vel_yaw[i];
344  tr_desired->command[i] = t.command[i];
345  };
346 
347  tr_desired->header = m_uas->synchronized_header("local_origin", trajectory.time_usec);
348 
349  for (int i = 0; i < trajectory.valid_points; ++i)
350  {
351  tr_desired->point_valid[i] = true;
352  }
353 
354  for (int i = trajectory.valid_points; i < NUM_POINTS; ++i)
355  {
356  tr_desired->point_valid[i] = false;
357  }
358 
359  // [[[cog:
360  // for i in range(5):
361  // cog.outl(
362  // "fill_msg_point(tr_desired->point_{i1}, trajectory, {i0});"
363  // .format(i0=i, i1=i + 1, )
364  // )
365  // ]]]
366  fill_msg_point(tr_desired->point_1, trajectory, 0);
367  fill_msg_point(tr_desired->point_2, trajectory, 1);
368  fill_msg_point(tr_desired->point_3, trajectory, 2);
369  fill_msg_point(tr_desired->point_4, trajectory, 3);
370  fill_msg_point(tr_desired->point_5, trajectory, 4);
371  // [[[end]]] (checksum: b6aa0c7395a7a426c25d726b75b6efea)
372 
373  trajectory_desired_pub.publish(tr_desired);
374  }
375 
376  float wrap_pi(float a)
377  {
378  if (!std::isfinite(a)) {
379  return a;
380  }
381 
382  return fmod(a + M_PI, 2.0f * M_PI) - M_PI;
383  }
384 };
385 } // namespace extra_plugins
386 } // namespace mavros
387 
std::shared_ptr< MAVConnInterface const > ConstPtr
std_msgs::Header synchronized_header(const std::string &frame_id, const T time_stamp)
void publish(const boost::shared_ptr< M > &message) const
void fill_points_velocity(MavPoints &x, MavPoints &y, MavPoints &z, const geometry_msgs::Vector3 &velocity, const size_t i)
Definition: trajectory.cpp:98
Subscriber subscribe(const std::string &topic, uint32_t queue_size, void(T::*fp)(M), T *obj, const TransportHints &transport_hints=TransportHints())
std::array< float, NUM_POINTS > MavPoints
Type matching mavlink::common::msg::TRAJECTORY::TRAJECTORY_REPRESENTATION_WAYPOINTS fields...
Definition: trajectory.cpp:30
void fill_points_acceleration(MavPoints &x, MavPoints &y, MavPoints &z, const geometry_msgs::Vector3 &acceleration, const size_t i)
Definition: trajectory.cpp:107
HandlerInfo make_handler(const mavlink::msgid_t id, void(_C::*fn)(const mavlink::mavlink_message_t *msg, const mavconn::Framing framing))
void fill_points_yaw_speed(MavPoints &yv, const double yaw_speed, const size_t i)
Definition: trajectory.cpp:123
T transform_orientation_enu_ned(const T &in)
void handle_trajectory(const mavlink::mavlink_message_t *msg, mavlink::common::msg::TRAJECTORY_REPRESENTATION_WAYPOINTS &trajectory)
Definition: trajectory.cpp:334
static constexpr size_t NUM_POINTS
Points count in TRAJECTORY message.
Definition: trajectory.cpp:27
void fill_points_yaw_wp(MavPoints &y, const double yaw, const size_t i)
Definition: trajectory.cpp:119
void fill_points_all_unused(mavlink::common::msg::TRAJECTORY_REPRESENTATION_WAYPOINTS &t, const size_t i)
Definition: trajectory.cpp:150
void fill_points_position(MavPoints &x, MavPoints &y, MavPoints &z, const geometry_msgs::Point &position, const size_t i)
Definition: trajectory.cpp:89
void fill_msg_position(geometry_msgs::Point &position, const mavlink::common::msg::TRAJECTORY_REPRESENTATION_WAYPOINTS &t, const size_t i)
Definition: trajectory.cpp:177
void fill_points_all_unused_bezier(mavlink::common::msg::TRAJECTORY_REPRESENTATION_BEZIER &t, const size_t i)
Definition: trajectory.cpp:167
#define UAS_FCU(uasobjptr)
T transform_frame_ned_enu(const T &in)
Eigen::Vector3d to_eigen(const geometry_msgs::Point r)
auto fill_points_unused_path(mavlink::common::msg::TRAJECTORY_REPRESENTATION_WAYPOINTS &t, const size_t i)
Definition: trajectory.cpp:140
mavros_msgs::PositionTarget RosPoints
Definition: trajectory.cpp:32
Publisher advertise(const std::string &topic, uint32_t queue_size, bool latch=false)
T transform_frame_enu_ned(const T &in)
void fill_points_yaw_q(MavPoints &y, const geometry_msgs::Quaternion &orientation, const size_t i)
Definition: trajectory.cpp:127
void path_cb(const nav_msgs::Path::ConstPtr &req)
Send corrected path to the FCU.
Definition: trajectory.cpp:298
std::vector< HandlerInfo > Subscriptions
Subscriptions get_subscriptions() override
Definition: trajectory.cpp:55
double quaternion_get_yaw(const Eigen::Quaterniond &q)
void trajectory_cb(const mavros_msgs::Trajectory::ConstPtr &req)
Send corrected path to the FCU.
Definition: trajectory.cpp:213
Trajectory plugin to receive planned path from the FCU and send back to the FCU a corrected path (col...
Definition: trajectory.cpp:40
void fill_msg_acceleration(geometry_msgs::Vector3 &acceleration, const mavlink::common::msg::TRAJECTORY_REPRESENTATION_WAYPOINTS &t, const size_t i)
Definition: trajectory.cpp:195
void initialize(UAS &uas_) override
Definition: trajectory.cpp:46
T transform_orientation_baselink_aircraft(const T &in)
void initialize(UAS &uas_) override
void fill_msg_velocity(geometry_msgs::Vector3 &velocity, const mavlink::common::msg::TRAJECTORY_REPRESENTATION_WAYPOINTS &t, const size_t i)
Definition: trajectory.cpp:186
#define ROS_ASSERT(cond)
#define PLUGINLIB_EXPORT_CLASS(class_type, base_class_type)
void fill_points_delta(MavPoints &y, const double time_horizon, const size_t i)
Definition: trajectory.cpp:136
constexpr std::underlying_type< _T >::type enum_value(_T e)


mavros_extras
Author(s): Vladimir Ermakov , Amilcar Lucas
autogenerated on Tue Jun 1 2021 02:36:36