PX4 Firmware
PX4 Autopilot Software http://px4.io
input_mavlink.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 *
3 * Copyright (c) 2016-2017 PX4 Development Team. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in
13 * the documentation and/or other materials provided with the
14 * distribution.
15 * 3. Neither the name PX4 nor the names of its contributors may be
16 * used to endorse or promote products derived from this software
17 * without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
22 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
23 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
24 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
25 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
26 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
27 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
29 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 * POSSIBILITY OF SUCH DAMAGE.
31 *
32 ****************************************************************************/
33 
34 /**
35  * @file input_mavlink.cpp
36  * @author Leon Müller (thedevleon)
37  * @author Beat Küng <beat-kueng@gmx.net>
38  *
39  */
40 
41 #include "input_mavlink.h"
46 #include <drivers/drv_hrt.h>
47 #include <lib/parameters/param.h>
48 #include <px4_platform_common/defines.h>
49 #include <px4_platform_common/posix.h>
50 #include <errno.h>
51 #include <math.h>
52 
53 namespace vmount
54 {
55 
57 {
58  if (_vehicle_roi_sub >= 0) {
60  }
61 
64  }
65 }
66 
68 {
69  _vehicle_roi_sub = orb_subscribe(ORB_ID(vehicle_roi));
70 
71  if (_vehicle_roi_sub < 0) {
72  return -errno;
73  }
74 
75  _position_setpoint_triplet_sub = orb_subscribe(ORB_ID(position_setpoint_triplet));
76 
78  return -errno;
79  }
80 
81  return 0;
82 }
83 
84 int InputMavlinkROI::update_impl(unsigned int timeout_ms, ControlData **control_data, bool already_active)
85 {
86  // already_active is unused, we don't care what happened previously.
87 
88  // Default to no change, set if we receive anything.
89  *control_data = nullptr;
90 
91  const int num_poll = 2;
92  px4_pollfd_struct_t polls[num_poll];
93  polls[0].fd = _vehicle_roi_sub;
94  polls[0].events = POLLIN;
95  polls[1].fd = _position_setpoint_triplet_sub;
96  polls[1].events = POLLIN;
97 
98  int ret = px4_poll(polls, num_poll, timeout_ms);
99 
100  if (ret < 0) {
101  return -errno;
102  }
103 
104  if (ret == 0) {
105  // Timeout, _control_data is already null
106 
107  } else {
108  if (polls[0].revents & POLLIN) {
109  vehicle_roi_s vehicle_roi;
110  orb_copy(ORB_ID(vehicle_roi), _vehicle_roi_sub, &vehicle_roi);
111 
113 
114  if (vehicle_roi.mode == vehicle_roi_s::ROI_NONE) {
115 
117  *control_data = &_control_data;
118 
119  } else if (vehicle_roi.mode == vehicle_roi_s::ROI_WPNEXT) {
123 
127 
128  *control_data = &_control_data;
129 
130  } else if (vehicle_roi.mode == vehicle_roi_s::ROI_LOCATION) {
131  control_data_set_lon_lat(vehicle_roi.lon, vehicle_roi.lat, vehicle_roi.alt);
132 
133  *control_data = &_control_data;
134 
135  } else if (vehicle_roi.mode == vehicle_roi_s::ROI_TARGET) {
136  //TODO is this even suported?
137  }
138 
139  _cur_roi_mode = vehicle_roi.mode;
140 
141  //set all other control data fields to defaults
142  for (int i = 0; i < 3; ++i) {
143  _control_data.stabilize_axis[i] = false;
144  }
145  }
146 
147  // check whether the position setpoint got updated
148  if (polls[1].revents & POLLIN) {
149  if (_cur_roi_mode == vehicle_roi_s::ROI_WPNEXT) {
151  *control_data = &_control_data;
152 
153  } else { // must do an orb_copy() in *every* case
154  position_setpoint_triplet_s position_setpoint_triplet;
155  orb_copy(ORB_ID(position_setpoint_triplet), _position_setpoint_triplet_sub, &position_setpoint_triplet);
156  }
157  }
158  }
159 
160  return 0;
161 }
162 
164 {
165  position_setpoint_triplet_s position_setpoint_triplet;
166  orb_copy(ORB_ID(position_setpoint_triplet), _position_setpoint_triplet_sub, &position_setpoint_triplet);
167  _control_data.type_data.lonlat.lon = position_setpoint_triplet.current.lon;
168  _control_data.type_data.lonlat.lat = position_setpoint_triplet.current.lat;
169  _control_data.type_data.lonlat.altitude = position_setpoint_triplet.current.alt;
170 }
171 
173 {
174  PX4_INFO("Input: Mavlink (ROI)");
175 }
176 
177 
179  : _stabilize {stabilize, stabilize, stabilize}
180 {
181  param_t handle = param_find("MAV_SYS_ID");
182 
183  if (handle != PARAM_INVALID) {
184  param_get(handle, &_mav_sys_id);
185  }
186 
187  handle = param_find("MAV_COMP_ID");
188 
189  if (handle != PARAM_INVALID) {
190  param_get(handle, &_mav_comp_id);
191  }
192 }
193 
195 {
196  if (_vehicle_command_sub >= 0) {
198  }
199 }
200 
202 {
203  if ((_vehicle_command_sub = orb_subscribe(ORB_ID(vehicle_command))) < 0) {
204  return -errno;
205  }
206 
207  // rate-limit inputs to 100Hz. If we don't do this and the output is configured to mavlink mode,
208  // it will publish vehicle_command's as well, causing the input poll() in here to return
209  // immediately, which in turn will cause an output update and thus a busy loop.
211 
212  return 0;
213 }
214 
215 
216 int InputMavlinkCmdMount::update_impl(unsigned int timeout_ms, ControlData **control_data, bool already_active)
217 {
218  // Default to notify that there was no change.
219  *control_data = nullptr;
220 
221  const int num_poll = 1;
222  px4_pollfd_struct_t polls[num_poll];
223  polls[0].fd = _vehicle_command_sub;
224  polls[0].events = POLLIN;
225 
226  int poll_timeout = (int)timeout_ms;
227 
228  bool exit_loop = false;
229 
230  while (!exit_loop && poll_timeout >= 0) {
231  hrt_abstime poll_start = hrt_absolute_time();
232 
233  int ret = px4_poll(polls, num_poll, poll_timeout);
234 
235  if (ret < 0) {
236  return -errno;
237  }
238 
239  poll_timeout -= (hrt_absolute_time() - poll_start) / 1000;
240 
241  // if we get a command that we need to handle, we exit the loop, otherwise we poll until we reach the timeout
242  exit_loop = true;
243 
244  if (ret == 0) {
245  // Timeout control_data already null.
246 
247  } else {
248  if (polls[0].revents & POLLIN) {
249  vehicle_command_s vehicle_command;
250  orb_copy(ORB_ID(vehicle_command), _vehicle_command_sub, &vehicle_command);
251 
252  // Process only if the command is for us or for anyone (component id 0).
253  const bool sysid_correct = (vehicle_command.target_system == _mav_sys_id);
254  const bool compid_correct = ((vehicle_command.target_component == _mav_comp_id) ||
255  (vehicle_command.target_component == 0));
256 
257  if (!sysid_correct || !compid_correct) {
258  exit_loop = false;
259  continue;
260  }
261 
262  for (int i = 0; i < 3; ++i) {
264  }
265 
267 
268  if (vehicle_command.command == vehicle_command_s::VEHICLE_CMD_DO_MOUNT_CONTROL) {
269 
270  switch ((int)vehicle_command.param7) {
271  case vehicle_command_s::VEHICLE_MOUNT_MODE_RETRACT:
273 
274  /* FALLTHROUGH */
275 
276  case vehicle_command_s::VEHICLE_MOUNT_MODE_NEUTRAL:
278 
279  *control_data = &_control_data;
280  break;
281 
282  case vehicle_command_s::VEHICLE_MOUNT_MODE_MAVLINK_TARGETING:
287  // vmount spec has roll on channel 0, MAVLink spec has pitch on channel 0
288  _control_data.type_data.angle.angles[0] = vehicle_command.param2 * M_DEG_TO_RAD_F;
289  // vmount spec has pitch on channel 1, MAVLink spec has roll on channel 1
290  _control_data.type_data.angle.angles[1] = vehicle_command.param1 * M_DEG_TO_RAD_F;
291  // both specs have yaw on channel 2
292  _control_data.type_data.angle.angles[2] = vehicle_command.param3 * M_DEG_TO_RAD_F;
293 
294  // We expect angle of [-pi..+pi]. If the input range is [0..2pi] we can fix that.
297  }
298 
299  *control_data = &_control_data;
300  break;
301 
302  case vehicle_command_s::VEHICLE_MOUNT_MODE_RC_TARGETING:
303  break;
304 
305  case vehicle_command_s::VEHICLE_MOUNT_MODE_GPS_POINT:
306  control_data_set_lon_lat((double)vehicle_command.param2, (double)vehicle_command.param1, vehicle_command.param3);
307 
308  *control_data = &_control_data;
309  break;
310  }
311 
312  _ack_vehicle_command(&vehicle_command);
313 
314  } else if (vehicle_command.command == vehicle_command_s::VEHICLE_CMD_DO_MOUNT_CONFIGURE) {
315  _stabilize[0] = (uint8_t) vehicle_command.param2 == 1;
316  _stabilize[1] = (uint8_t) vehicle_command.param3 == 1;
317  _stabilize[2] = (uint8_t) vehicle_command.param4 == 1;
318  _control_data.type = ControlData::Type::Neutral; //always switch to neutral position
319 
320  *control_data = &_control_data;
321  _ack_vehicle_command(&vehicle_command);
322 
323  } else {
324  exit_loop = false;
325  }
326  }
327 
328  }
329  }
330 
331  return 0;
332 }
333 
335 {
336  vehicle_command_ack_s vehicle_command_ack{};
337 
338  vehicle_command_ack.timestamp = hrt_absolute_time();
339  vehicle_command_ack.command = cmd->command;
340  vehicle_command_ack.result = vehicle_command_s::VEHICLE_CMD_RESULT_ACCEPTED;
341  vehicle_command_ack.target_system = cmd->source_system;
342  vehicle_command_ack.target_component = cmd->source_component;
343 
344  uORB::PublicationQueued<vehicle_command_ack_s> cmd_ack_pub{ORB_ID(vehicle_command_ack)};
345  cmd_ack_pub.publish(vehicle_command_ack);
346 }
347 
349 {
350  PX4_INFO("Input: Mavlink (CMD_MOUNT)");
351 }
352 
353 
354 } /* namespace vmount */
struct vmount::ControlData::TypeData::TypeLonLat lonlat
#define PARAM_INVALID
Handle returned when a parameter cannot be found.
Definition: param.h:103
float yaw_angle_offset
angular offset for yaw [rad]
Definition: common.h:79
int orb_copy(const struct orb_metadata *meta, int handle, void *buffer)
Definition: uORB.cpp:90
double lon
longitude in [deg]
Definition: common.h:74
static int timeout_ms
__EXPORT int param_get(param_t param, void *val)
Copy the value of a parameter.
Definition: parameters.cpp:589
float pitch_angle_offset
angular offset for pitch [rad]
Definition: common.h:78
float pitch_fixed_angle
ignored if < -pi, otherwise use a fixed pitch angle instead of the altitude
Definition: common.h:80
int orb_set_interval(int handle, unsigned interval)
Definition: uORB.cpp:126
ControlData _control_data
Definition: input.h:83
int px4_poll(px4_pollfd_struct_t *fds, nfds_t nfds, int timeout)
float altitude
altitude in [m]
Definition: common.h:76
move to neutral position
Definition: common.h:45
float roll_angle
roll is set to a fixed angle.
Definition: common.h:77
High-resolution timer with callouts and timekeeping.
Global flash based parameter store.
int orb_subscribe(const struct orb_metadata *meta)
Definition: uORB.cpp:75
bool gimbal_shutter_retract
whether to lock the gimbal (only in RC output mode)
Definition: common.h:88
#define ORB_ID(_name)
Generates a pointer to the uORB metadata structure for a given topic.
Definition: uORB.h:87
struct position_setpoint_s current
double lat
latitude in [deg]
Definition: common.h:75
int orb_unsubscribe(int handle)
Definition: uORB.cpp:85
float angles[3]
attitude angles (roll, pitch, yaw) in rad, [-pi, +pi] if is_speed[i] == false
Definition: common.h:68
__BEGIN_DECLS typedef uint64_t hrt_abstime
Absolute time, in microsecond units.
Definition: drv_hrt.h:58
This defines the common API between an input and an output of the vmount driver.
Definition: common.h:55
uint8_t mode
Definition: vehicle_roi.h:66
float pitch_offset
Definition: vehicle_roi.h:64
__EXPORT param_t param_find(const char *name)
Look up a parameter by name.
Definition: parameters.cpp:370
float roll_offset
Definition: vehicle_roi.h:63
bool is_speed[3]
if true, the angle is the angular speed in rad/s
Definition: common.h:70
float yaw_offset
Definition: vehicle_roi.h:65
control the roll, pitch & yaw angle directly
struct vmount::ControlData::TypeData::TypeAngle angle
#define M_PI_F
Definition: ashtech.cpp:44
void control_data_set_lon_lat(double lon, double lat, float altitude, float roll_angle=0.f, float pitch_fixed_angle=-10.f)
Definition: input.cpp:66
bool stabilize_axis[3]
whether the vmount driver should stabilize an axis (if the output supports it, this can also be done ...
Definition: common.h:85
__EXPORT hrt_abstime hrt_absolute_time(void)
Get absolute time in [us] (does not wrap).
uint32_t param_t
Parameter handle.
Definition: param.h:98
union vmount::ControlData::TypeData type_data