PX4 Firmware
PX4 Autopilot Software http://px4.io
vmount.cpp
Go to the documentation of this file.
1 /****************************************************************************
2  *
3  * Copyright (c) 2013-2019 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 vmount.cpp
36  * @author Leon Müller (thedevleon)
37  * @author Beat Küng <beat-kueng@gmx.net>
38  * @author Julian Oes <julian@oes.ch>
39  * @author Matthew Edwards (mje-nz)
40  *
41  * Driver for to control mounts such as gimbals or servos.
42  * Inputs for the mounts can RC and/or mavlink commands.
43  * Outputs to the mounts can be RC (PWM) output or mavlink.
44  */
45 
46 #include <math.h>
47 #include <stdlib.h>
48 #include <stdio.h>
49 #include <stdbool.h>
50 #include <string.h>
51 #include <sys/types.h>
52 #include <fcntl.h>
53 #include <unistd.h>
54 #include <systemlib/err.h>
55 #include <lib/parameters/param.h>
56 #include <px4_platform_common/defines.h>
57 #include <px4_platform_common/tasks.h>
58 
59 #include "input_mavlink.h"
60 #include "input_rc.h"
61 #include "input_test.h"
62 #include "output_rc.h"
63 #include "output_mavlink.h"
64 
65 #include <uORB/Subscription.hpp>
67 
68 #include <px4_platform_common/px4_config.h>
69 #include <px4_platform_common/module.h>
70 
71 using namespace vmount;
72 
73 /* thread state */
74 static volatile bool thread_should_exit = false;
75 static volatile bool thread_running = false;
76 
77 static constexpr int input_objs_len_max = 3;
78 
79 struct ThreadData {
80  InputBase *input_objs[input_objs_len_max] = {nullptr, nullptr, nullptr};
81  int input_objs_len = 0;
82  OutputBase *output_obj = nullptr;
83 };
84 static volatile ThreadData *g_thread_data = nullptr;
85 
86 struct Parameters {
87  int32_t mnt_mode_in;
88  int32_t mnt_mode_out;
89  int32_t mnt_mav_sysid;
90  int32_t mnt_mav_compid;
93  int32_t mnt_man_pitch;
94  int32_t mnt_man_roll;
95  int32_t mnt_man_yaw;
96  int32_t mnt_do_stab;
102  float mnt_off_yaw;
103 
104  bool operator!=(const Parameters &p)
105  {
106 #pragma GCC diagnostic push
107 #pragma GCC diagnostic ignored "-Wfloat-equal"
108  return mnt_mode_in != p.mnt_mode_in ||
109  mnt_mode_out != p.mnt_mode_out ||
110  mnt_mav_sysid != p.mnt_mav_sysid ||
111  mnt_mav_compid != p.mnt_mav_compid ||
112  fabsf(mnt_ob_lock_mode - p.mnt_ob_lock_mode) > 1e-6f ||
113  fabsf(mnt_ob_norm_mode - p.mnt_ob_norm_mode) > 1e-6f ||
114  mnt_man_pitch != p.mnt_man_pitch ||
115  mnt_man_roll != p.mnt_man_roll ||
116  mnt_man_yaw != p.mnt_man_yaw ||
117  mnt_do_stab != p.mnt_do_stab ||
118  mnt_range_pitch != p.mnt_range_pitch ||
119  mnt_range_roll != p.mnt_range_roll ||
120  mnt_range_yaw != p.mnt_range_yaw ||
121  mnt_off_pitch != p.mnt_off_pitch ||
122  mnt_off_roll != p.mnt_off_roll ||
123  mnt_off_yaw != p.mnt_off_yaw;
124 #pragma GCC diagnostic pop
125 
126  }
127 };
128 
146 };
147 
148 
149 /* functions */
150 static void usage();
151 static void update_params(ParameterHandles &param_handles, Parameters &params, bool &got_changes);
152 static bool get_params(ParameterHandles &param_handles, Parameters &params);
153 
154 static int vmount_thread_main(int argc, char *argv[]);
155 extern "C" __EXPORT int vmount_main(int argc, char *argv[]);
156 
157 static int vmount_thread_main(int argc, char *argv[])
158 {
159  ParameterHandles param_handles;
160  Parameters params {};
161  OutputConfig output_config;
162  ThreadData thread_data;
163 
164  InputTest *test_input = nullptr;
165 
166 #ifdef __PX4_NUTTX
167  /* the NuttX optarg handler does not
168  * ignore argv[0] like the POSIX handler
169  * does, nor does it deal with non-flag
170  * verbs well. So we Remove the application
171  * name and the verb.
172  */
173  argc -= 1;
174  argv += 1;
175 #endif
176 
177  if (argc > 0 && !strcmp(argv[0], "test")) {
178  PX4_INFO("Starting in test mode");
179 
180  const char *axis_names[3] = {"roll", "pitch", "yaw"};
181  float angles[3] = { 0.f, 0.f, 0.f };
182 
183  if (argc == 3) {
184  bool found_axis = false;
185 
186  for (int i = 0 ; i < 3; ++i) {
187  if (!strcmp(argv[1], axis_names[i])) {
188  long angle_deg = strtol(argv[2], nullptr, 0);
189  angles[i] = (float)angle_deg;
190  found_axis = true;
191  }
192  }
193 
194  if (!found_axis) {
195  usage();
196  return -1;
197  }
198 
199  test_input = new InputTest(angles[0], angles[1], angles[2]);
200 
201  if (!test_input) {
202  PX4_ERR("memory allocation failed");
203  return -1;
204  }
205 
206  } else {
207  usage();
208  return -1;
209  }
210  }
211 
212  if (!get_params(param_handles, params)) {
213  PX4_ERR("could not get mount parameters!");
214  delete test_input;
215  return -1;
216  }
217 
218  uORB::Subscription parameter_update_sub{ORB_ID(parameter_update)};
219  thread_running = true;
220  ControlData *control_data = nullptr;
221  g_thread_data = &thread_data;
222 
223  int last_active = 0;
224 
225  while (!thread_should_exit) {
226 
227  if (!thread_data.input_objs[0] && (params.mnt_mode_in >= 0 || test_input)) { //need to initialize
228 
229  output_config.gimbal_normal_mode_value = params.mnt_ob_norm_mode;
230  output_config.gimbal_retracted_mode_value = params.mnt_ob_lock_mode;
231  output_config.pitch_scale = 1.0f / ((params.mnt_range_pitch / 2.0f) * M_DEG_TO_RAD_F);
232  output_config.roll_scale = 1.0f / ((params.mnt_range_roll / 2.0f) * M_DEG_TO_RAD_F);
233  output_config.yaw_scale = 1.0f / ((params.mnt_range_yaw / 2.0f) * M_DEG_TO_RAD_F);
234  output_config.pitch_offset = params.mnt_off_pitch * M_DEG_TO_RAD_F;
235  output_config.roll_offset = params.mnt_off_roll * M_DEG_TO_RAD_F;
236  output_config.yaw_offset = params.mnt_off_yaw * M_DEG_TO_RAD_F;
237  output_config.mavlink_sys_id = params.mnt_mav_sysid;
238  output_config.mavlink_comp_id = params.mnt_mav_compid;
239 
240  bool alloc_failed = false;
241  thread_data.input_objs_len = 1;
242 
243  if (test_input) {
244  thread_data.input_objs[0] = test_input;
245 
246  } else {
247  switch (params.mnt_mode_in) {
248  case 0:
249 
250  // Automatic
251  thread_data.input_objs[0] = new InputMavlinkCmdMount(params.mnt_do_stab);
252  thread_data.input_objs[1] = new InputMavlinkROI();
253 
254  // RC is on purpose last here so that if there are any mavlink
255  // messages, they will take precedence over RC.
256  // This logic is done further below while update() is called.
257  thread_data.input_objs[2] = new InputRC(params.mnt_do_stab, params.mnt_man_roll, params.mnt_man_pitch,
258  params.mnt_man_yaw);
259  thread_data.input_objs_len = 3;
260 
261  break;
262 
263  case 1: //RC
264  thread_data.input_objs[0] = new InputRC(params.mnt_do_stab, params.mnt_man_roll, params.mnt_man_pitch,
265  params.mnt_man_yaw);
266  break;
267 
268  case 2: //MAVLINK_ROI
269  thread_data.input_objs[0] = new InputMavlinkROI();
270  break;
271 
272  case 3: //MAVLINK_DO_MOUNT
273  thread_data.input_objs[0] = new InputMavlinkCmdMount(params.mnt_do_stab);
274  break;
275 
276  default:
277  PX4_ERR("invalid input mode %i", params.mnt_mode_in);
278  break;
279  }
280  }
281 
282  for (int i = 0; i < thread_data.input_objs_len; ++i) {
283  if (!thread_data.input_objs[i]) {
284  alloc_failed = true;
285  }
286  }
287 
288  switch (params.mnt_mode_out) {
289  case 0: //AUX
290  thread_data.output_obj = new OutputRC(output_config);
291 
292  if (!thread_data.output_obj) { alloc_failed = true; }
293 
294  break;
295 
296  case 1: //MAVLINK
297  thread_data.output_obj = new OutputMavlink(output_config);
298 
299  if (!thread_data.output_obj) { alloc_failed = true; }
300 
301  break;
302 
303  default:
304  PX4_ERR("invalid output mode %i", params.mnt_mode_out);
305  thread_should_exit = true;
306  break;
307  }
308 
309  if (alloc_failed) {
310  thread_data.input_objs_len = 0;
311  PX4_ERR("memory allocation failed");
312  thread_should_exit = true;
313  }
314 
315  if (thread_should_exit) {
316  break;
317  }
318 
319  int ret = thread_data.output_obj->initialize();
320 
321  if (ret) {
322  PX4_ERR("failed to initialize output mode (%i)", ret);
323  thread_should_exit = true;
324  break;
325  }
326  }
327 
328  if (thread_data.input_objs_len > 0) {
329 
330  //get input: we cannot make the timeout too large, because the output needs to update
331  //periodically for stabilization and angle updates.
332 
333  for (int i = 0; i < thread_data.input_objs_len; ++i) {
334 
335  bool already_active = (last_active == i);
336 
337  ControlData *control_data_to_check = nullptr;
338  unsigned int poll_timeout = already_active ? 50 : 0; // poll only on active input to reduce latency
339  int ret = thread_data.input_objs[i]->update(poll_timeout, &control_data_to_check, already_active);
340 
341  if (ret) {
342  PX4_ERR("failed to read input %i (ret: %i)", i, ret);
343  continue;
344  }
345 
346  if (control_data_to_check != nullptr || already_active) {
347  control_data = control_data_to_check;
348  last_active = i;
349  }
350  }
351 
352  //update output
353  int ret = thread_data.output_obj->update(control_data);
354 
355  if (ret) {
356  PX4_ERR("failed to write output (%i)", ret);
357  break;
358  }
359 
360  thread_data.output_obj->publish();
361 
362  } else {
363  //wait for parameter changes. We still need to wake up regularily to check for thread exit requests
364  px4_usleep(1e6);
365  }
366 
367  if (test_input && test_input->finished()) {
368  thread_should_exit = true;
369  break;
370  }
371 
372  // check for parameter updates
373  if (parameter_update_sub.updated()) {
374  // clear update
375  parameter_update_s pupdate;
376  parameter_update_sub.copy(&pupdate);
377 
378  // update parameters from storage
379  bool updated = false;
380  update_params(param_handles, params, updated);
381 
382  if (updated) {
383  //re-init objects
384  for (int i = 0; i < input_objs_len_max; ++i) {
385  if (thread_data.input_objs[i]) {
386  delete (thread_data.input_objs[i]);
387  thread_data.input_objs[i] = nullptr;
388  }
389  }
390 
391  thread_data.input_objs_len = 0;
392 
393  last_active = 0;
394 
395  if (thread_data.output_obj) {
396  delete (thread_data.output_obj);
397  thread_data.output_obj = nullptr;
398  }
399  }
400  }
401  }
402 
403  g_thread_data = nullptr;
404 
405  for (int i = 0; i < input_objs_len_max; ++i) {
406  if (thread_data.input_objs[i]) {
407  delete (thread_data.input_objs[i]);
408  thread_data.input_objs[i] = nullptr;
409  }
410  }
411 
412  thread_data.input_objs_len = 0;
413 
414  if (thread_data.output_obj) {
415  delete (thread_data.output_obj);
416  thread_data.output_obj = nullptr;
417  }
418 
419  thread_running = false;
420  return 0;
421 }
422 
423 /**
424  * The main command function.
425  * Processes command line arguments and starts the daemon.
426  */
427 int vmount_main(int argc, char *argv[])
428 {
429  if (argc < 2) {
430  PX4_ERR("missing command");
431  usage();
432  return -1;
433  }
434 
435  const bool found_start = !strcmp(argv[1], "start");
436  const bool found_test = !strcmp(argv[1], "test");
437 
438  if (found_start || found_test) {
439 
440  /* this is not an error */
441  if (thread_running) {
442  if (found_start) {
443  PX4_WARN("mount driver already running");
444  return 0;
445 
446  } else {
447  PX4_WARN("mount driver already running, run vmount stop before 'vmount test'");
448  return 1;
449  }
450  }
451 
452  thread_should_exit = false;
453  int vmount_task = px4_task_spawn_cmd("vmount",
454  SCHED_DEFAULT,
455  SCHED_PRIORITY_DEFAULT,
456  1900,
458  (char *const *)argv + 1);
459 
460  int counter = 0;
461 
462  while (!thread_running && vmount_task >= 0) {
463  px4_usleep(5000);
464 
465  if (++counter >= 100) {
466  break;
467  }
468  }
469 
470  if (vmount_task < 0) {
471  PX4_ERR("failed to start");
472  return -1;
473  }
474 
475  return counter < 100 || thread_should_exit ? 0 : -1;
476  }
477 
478  if (!strcmp(argv[1], "stop")) {
479 
480  /* this is not an error */
481  if (!thread_running) {
482  PX4_WARN("mount driver not running");
483  return 0;
484  }
485 
486  thread_should_exit = true;
487 
488  while (thread_running) {
489  px4_usleep(100000);
490  }
491 
492  return 0;
493  }
494 
495  if (!strcmp(argv[1], "status")) {
496  if (thread_running && g_thread_data) {
497 
498  for (int i = 0; i < g_thread_data->input_objs_len; ++i) {
499  g_thread_data->input_objs[i]->print_status();
500  }
501 
502  if (g_thread_data->input_objs_len == 0) {
503  PX4_INFO("Input: None");
504  }
505 
506  if (g_thread_data->output_obj) {
507  g_thread_data->output_obj->print_status();
508 
509  } else {
510  PX4_INFO("Output: None");
511  }
512 
513  } else {
514  PX4_INFO("not running");
515  }
516 
517  return 0;
518  }
519 
520  PX4_ERR("unrecognized command");
521  usage();
522  return -1;
523 }
524 
525 void update_params(ParameterHandles &param_handles, Parameters &params, bool &got_changes)
526 {
527  Parameters prev_params = params;
528  param_get(param_handles.mnt_mode_in, &params.mnt_mode_in);
529  param_get(param_handles.mnt_mode_out, &params.mnt_mode_out);
530  param_get(param_handles.mnt_mav_sysid, &params.mnt_mav_sysid);
531  param_get(param_handles.mnt_mav_compid, &params.mnt_mav_compid);
532  param_get(param_handles.mnt_ob_lock_mode, &params.mnt_ob_lock_mode);
533  param_get(param_handles.mnt_ob_norm_mode, &params.mnt_ob_norm_mode);
534  param_get(param_handles.mnt_man_pitch, &params.mnt_man_pitch);
535  param_get(param_handles.mnt_man_roll, &params.mnt_man_roll);
536  param_get(param_handles.mnt_man_yaw, &params.mnt_man_yaw);
537  param_get(param_handles.mnt_do_stab, &params.mnt_do_stab);
538  param_get(param_handles.mnt_range_pitch, &params.mnt_range_pitch);
539  param_get(param_handles.mnt_range_roll, &params.mnt_range_roll);
540  param_get(param_handles.mnt_range_yaw, &params.mnt_range_yaw);
541  param_get(param_handles.mnt_off_pitch, &params.mnt_off_pitch);
542  param_get(param_handles.mnt_off_roll, &params.mnt_off_roll);
543  param_get(param_handles.mnt_off_yaw, &params.mnt_off_yaw);
544 
545  got_changes = prev_params != params;
546 }
547 
548 bool get_params(ParameterHandles &param_handles, Parameters &params)
549 {
550  param_handles.mnt_mode_in = param_find("MNT_MODE_IN");
551  param_handles.mnt_mode_out = param_find("MNT_MODE_OUT");
552  param_handles.mnt_mav_sysid = param_find("MNT_MAV_SYSID");
553  param_handles.mnt_mav_compid = param_find("MNT_MAV_COMPID");
554  param_handles.mnt_ob_lock_mode = param_find("MNT_OB_LOCK_MODE");
555  param_handles.mnt_ob_norm_mode = param_find("MNT_OB_NORM_MODE");
556  param_handles.mnt_man_pitch = param_find("MNT_MAN_PITCH");
557  param_handles.mnt_man_roll = param_find("MNT_MAN_ROLL");
558  param_handles.mnt_man_yaw = param_find("MNT_MAN_YAW");
559  param_handles.mnt_do_stab = param_find("MNT_DO_STAB");
560  param_handles.mnt_range_pitch = param_find("MNT_RANGE_PITCH");
561  param_handles.mnt_range_roll = param_find("MNT_RANGE_ROLL");
562  param_handles.mnt_range_yaw = param_find("MNT_RANGE_YAW");
563  param_handles.mnt_off_pitch = param_find("MNT_OFF_PITCH");
564  param_handles.mnt_off_roll = param_find("MNT_OFF_ROLL");
565  param_handles.mnt_off_yaw = param_find("MNT_OFF_YAW");
566 
567  if (param_handles.mnt_mode_in == PARAM_INVALID ||
568  param_handles.mnt_mode_out == PARAM_INVALID ||
569  param_handles.mnt_mav_sysid == PARAM_INVALID ||
570  param_handles.mnt_mav_compid == PARAM_INVALID ||
571  param_handles.mnt_ob_lock_mode == PARAM_INVALID ||
572  param_handles.mnt_ob_norm_mode == PARAM_INVALID ||
573  param_handles.mnt_man_pitch == PARAM_INVALID ||
574  param_handles.mnt_man_roll == PARAM_INVALID ||
575  param_handles.mnt_man_yaw == PARAM_INVALID ||
576  param_handles.mnt_do_stab == PARAM_INVALID ||
577  param_handles.mnt_range_pitch == PARAM_INVALID ||
578  param_handles.mnt_range_roll == PARAM_INVALID ||
579  param_handles.mnt_range_yaw == PARAM_INVALID ||
580  param_handles.mnt_off_pitch == PARAM_INVALID ||
581  param_handles.mnt_off_roll == PARAM_INVALID ||
582  param_handles.mnt_off_yaw == PARAM_INVALID) {
583  return false;
584  }
585 
586  bool dummy;
587  update_params(param_handles, params, dummy);
588  return true;
589 }
590 
591 static void usage()
592 {
593  PRINT_MODULE_DESCRIPTION(
594  R"DESCR_STR(
595 ### Description
596 Mount (Gimbal) control driver. It maps several different input methods (eg. RC or MAVLink) to a configured
597 output (eg. AUX channels or MAVLink).
598 
599 Documentation how to use it is on the [gimbal_control](https://dev.px4.io/en/advanced/gimbal_control.html) page.
600 
601 ### Implementation
602 Each method is implemented in its own class, and there is a common base class for inputs and outputs.
603 They are connected via an API, defined by the `ControlData` data structure. This makes sure that each input method
604 can be used with each output method and new inputs/outputs can be added with minimal effort.
605 
606 ### Examples
607 Test the output by setting a fixed yaw angle (and the other axes to 0):
608 $ vmount stop
609 $ vmount test yaw 30
610 )DESCR_STR");
611 
612  PRINT_MODULE_USAGE_NAME("vmount", "driver");
613  PRINT_MODULE_USAGE_COMMAND("start");
614  PRINT_MODULE_USAGE_COMMAND_DESCR("test", "Test the output: set a fixed angle for one axis (vmount must not be running)");
615  PRINT_MODULE_USAGE_ARG("roll|pitch|yaw <angle>", "Specify an axis and an angle in degrees", false);
616  PRINT_MODULE_USAGE_DEFAULT_COMMANDS();
617 }
param_t mnt_range_yaw
Definition: vmount.cpp:142
#define PARAM_INVALID
Handle returned when a parameter cannot be found.
Definition: param.h:103
int32_t mnt_mode_out
Definition: vmount.cpp:88
uint32_t mavlink_sys_id
Mavlink target system id for mavlink output.
Definition: output.h:67
float pitch_offset
Offset for pitch channel in radians.
Definition: output.h:63
param_t mnt_do_stab
Definition: vmount.cpp:139
virtual int update(unsigned int timeout_ms, ControlData **control_data, bool already_active)
Wait for an input update, with a timeout.
Definition: input.cpp:46
int32_t mnt_do_stab
Definition: vmount.cpp:96
float yaw_scale
Scale factor for yaw channel (maps from angle in radians to actuator output in [-1,1]).
Definition: output.h:61
param_t mnt_mode_out
Definition: vmount.cpp:131
static volatile bool thread_running
Definition: vmount.cpp:75
__EXPORT int param_get(param_t param, void *val)
Copy the value of a parameter.
Definition: parameters.cpp:589
InputBase * input_objs[input_objs_len_max]
Definition: vmount.cpp:80
virtual int initialize()
Definition: output.cpp:80
static constexpr int input_objs_len_max
Definition: vmount.cpp:77
param_t mnt_man_roll
Definition: vmount.cpp:137
Definition: I2C.hpp:51
int input_objs_len
Definition: vmount.cpp:81
param_t mnt_ob_norm_mode
Definition: vmount.cpp:135
int32_t mnt_man_roll
Definition: vmount.cpp:94
param_t mnt_off_pitch
Definition: vmount.cpp:143
param_t mnt_ob_lock_mode
Definition: vmount.cpp:134
int32_t mnt_man_pitch
Definition: vmount.cpp:93
int32_t mnt_mode_in
Definition: vmount.cpp:87
class OutputRC Output via actuator_controls_2 topic
Definition: output_rc.h:55
float yaw_offset
Offset for yaw channel in radians.
Definition: output.h:65
param_t mnt_mav_compid
Definition: vmount.cpp:133
static void usage()
Definition: vmount.cpp:591
Definition: common.h:45
param_t mnt_range_roll
Definition: vmount.cpp:141
virtual int update(const ControlData *control_data)=0
Update the output.
Global flash based parameter store.
class InputRC RC input class using manual_control_setpoint topic
Definition: input_rc.h:55
float gimbal_normal_mode_value
Mixer output value for selecting gimbal normal mode.
Definition: output.h:54
class InputTest Send a single control command, configured via constructor arguments ...
Definition: input_test.h:51
param_t mnt_off_roll
Definition: vmount.cpp:144
param_t mnt_man_yaw
Definition: vmount.cpp:138
#define ORB_ID(_name)
Generates a pointer to the uORB metadata structure for a given topic.
Definition: uORB.h:87
float mnt_ob_lock_mode
Definition: vmount.cpp:91
float mnt_range_roll
Definition: vmount.cpp:98
float gimbal_retracted_mode_value
Mixer output value for selecting gimbal retracted mode.
Definition: output.h:53
int32_t mnt_man_yaw
Definition: vmount.cpp:95
class InputBase Base class for all driver input classes
Definition: input.h:52
Vector< float, 6 > f(float t, const Matrix< float, 6, 1 > &, const Matrix< float, 3, 1 > &)
Definition: integration.cpp:8
static volatile ThreadData * g_thread_data
Definition: vmount.cpp:84
param_t mnt_off_yaw
Definition: vmount.cpp:145
Simple error/warning functions, heavily inspired by the BSD functions of the same names...
static int vmount_thread_main(int argc, char *argv[])
Definition: vmount.cpp:157
static unsigned counter
Definition: safety.c:56
__EXPORT int vmount_main(int argc, char *argv[])
The main command function.
Definition: vmount.cpp:427
int32_t mnt_mav_sysid
Definition: vmount.cpp:89
float mnt_range_yaw
Definition: vmount.cpp:99
virtual void print_status()=0
report status to stdout
virtual void print_status()=0
report status to stdout
float mnt_range_pitch
Definition: vmount.cpp:97
This defines the common API between an input and an output of the vmount driver.
Definition: common.h:55
static bool get_params(ParameterHandles &param_handles, Parameters &params)
Definition: vmount.cpp:548
__EXPORT param_t param_find(const char *name)
Look up a parameter by name.
Definition: parameters.cpp:370
param_t mnt_range_pitch
Definition: vmount.cpp:140
static void update_params(ParameterHandles &param_handles, Parameters &params, bool &got_changes)
Definition: vmount.cpp:525
uint32_t mavlink_comp_id
Definition: output.h:68
float mnt_off_roll
Definition: vmount.cpp:101
float pitch_scale
Scale factor for pitch channel (maps from angle in radians to actuator output in [-1,1]).
Definition: output.h:57
param_t mnt_man_pitch
Definition: vmount.cpp:136
OutputBase * output_obj
Definition: vmount.cpp:82
void publish()
Publish _angle_outputs as a mount_orientation message.
Definition: output.cpp:93
float roll_scale
Scale factor for roll channel (maps from angle in radians to actuator output in [-1,1]).
Definition: output.h:59
param_t mnt_mav_sysid
Definition: vmount.cpp:132
float mnt_off_yaw
Definition: vmount.cpp:102
param_t mnt_mode_in
Definition: vmount.cpp:130
class OutputBase Base class for all driver output classes
Definition: output.h:76
static volatile bool thread_should_exit
Definition: vmount.cpp:74
float mnt_ob_norm_mode
Definition: vmount.cpp:92
float roll_offset
Offset for roll channel in radians.
Definition: output.h:64
bool finished()
check whether the test finished, and thus the main thread can quit
Definition: input_test.cpp:57
int32_t mnt_mav_compid
Definition: vmount.cpp:90
bool operator!=(const Parameters &p)
Definition: vmount.cpp:104
float mnt_off_pitch
Definition: vmount.cpp:100
uint32_t param_t
Parameter handle.
Definition: param.h:98