51 #include <sys/types.h>    56 #include <px4_platform_common/defines.h>    57 #include <px4_platform_common/tasks.h>    68 #include <px4_platform_common/px4_config.h>    69 #include <px4_platform_common/module.h>    81     int input_objs_len = 0;
   106 #pragma GCC diagnostic push   107 #pragma GCC diagnostic ignored "-Wfloat-equal"   124 #pragma GCC diagnostic pop   177     if (argc > 0 && !strcmp(argv[0], 
"test")) {
   178         PX4_INFO(
"Starting in test mode");
   180         const char *axis_names[3] = {
"roll", 
"pitch", 
"yaw"};
   181         float angles[3] = { 0.f, 0.f, 0.f };
   184             bool found_axis = 
false;
   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;
   199             test_input = 
new InputTest(angles[0], angles[1], angles[2]);
   202                 PX4_ERR(
"memory allocation failed");
   213         PX4_ERR(
"could not get mount parameters!");
   221     g_thread_data = &thread_data;
   227         if (!thread_data.
input_objs[0] && (params.mnt_mode_in >= 0 || test_input)) { 
   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;
   240             bool alloc_failed = 
false;
   247                 switch (params.mnt_mode_in) {
   257                     thread_data.
input_objs[2] = 
new InputRC(params.mnt_do_stab, params.mnt_man_roll, params.mnt_man_pitch,
   264                     thread_data.
input_objs[0] = 
new InputRC(params.mnt_do_stab, params.mnt_man_roll, params.mnt_man_pitch,
   277                     PX4_ERR(
"invalid input mode %i", params.mnt_mode_in);
   288             switch (params.mnt_mode_out) {
   292                 if (!thread_data.
output_obj) { alloc_failed = 
true; }
   299                 if (!thread_data.
output_obj) { alloc_failed = 
true; }
   304                 PX4_ERR(
"invalid output mode %i", params.mnt_mode_out);
   311                 PX4_ERR(
"memory allocation failed");
   322                 PX4_ERR(
"failed to initialize output mode (%i)", ret);
   335                 bool already_active = (last_active == i);
   338                 unsigned int poll_timeout = already_active ? 50 : 0; 
   339                 int ret = thread_data.
input_objs[i]->
update(poll_timeout, &control_data_to_check, already_active);
   342                     PX4_ERR(
"failed to read input %i (ret: %i)", i, ret);
   346                 if (control_data_to_check != 
nullptr || already_active) {
   347                     control_data = control_data_to_check;
   356                 PX4_ERR(
"failed to write output (%i)", ret);
   367         if (test_input && test_input->
finished()) {
   373         if (parameter_update_sub.updated()) {
   376             parameter_update_sub.copy(&pupdate);
   379             bool updated = 
false;
   403     g_thread_data = 
nullptr;
   430         PX4_ERR(
"missing command");
   435     const bool found_start = !strcmp(argv[1], 
"start");
   436     const bool found_test = !strcmp(argv[1], 
"test");
   438     if (found_start || found_test) {
   443                 PX4_WARN(
"mount driver already running");
   447                 PX4_WARN(
"mount driver already running, run vmount stop before 'vmount test'");
   453         int vmount_task = px4_task_spawn_cmd(
"vmount",
   455                              SCHED_PRIORITY_DEFAULT,
   458                              (
char *
const *)argv + 1);
   465             if (++counter >= 100) {
   470         if (vmount_task < 0) {
   471             PX4_ERR(
"failed to start");
   478     if (!strcmp(argv[1], 
"stop")) {
   482             PX4_WARN(
"mount driver not running");
   495     if (!strcmp(argv[1], 
"status")) {
   503                 PX4_INFO(
"Input: None");
   510                 PX4_INFO(
"Output: None");
   514             PX4_INFO(
"not running");
   520     PX4_ERR(
"unrecognized command");
   545     got_changes = prev_params != params;
   593     PRINT_MODULE_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).   599 Documentation how to use it is on the [gimbal_control](https://dev.px4.io/en/advanced/gimbal_control.html) page.   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.   607 Test the output by setting a fixed yaw angle (and the other axes to 0):   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();
 
#define PARAM_INVALID
Handle returned when a parameter cannot be found. 
uint32_t mavlink_sys_id
Mavlink target system id for mavlink output. 
float pitch_offset
Offset for pitch channel in radians. 
float yaw_scale
Scale factor for yaw channel (maps from angle in radians to actuator output in [-1,1]). 
static volatile bool thread_running
__EXPORT int param_get(param_t param, void *val)
Copy the value of a parameter. 
InputBase * input_objs[input_objs_len_max]
static constexpr int input_objs_len_max
class OutputRC Output via actuator_controls_2 topic 
float yaw_offset
Offset for yaw channel in radians. 
class OutputMavlink Output via vehicle_command topic 
virtual int update(const ControlData *control_data)=0
Update the output. 
Global flash based parameter store. 
float gimbal_normal_mode_value
Mixer output value for selecting gimbal normal mode. 
#define ORB_ID(_name)
Generates a pointer to the uORB metadata structure for a given topic. 
float gimbal_retracted_mode_value
Mixer output value for selecting gimbal retracted mode. 
Vector< float, 6 > f(float t, const Matrix< float, 6, 1 > &, const Matrix< float, 3, 1 > &)
static volatile ThreadData * g_thread_data
Simple error/warning functions, heavily inspired by the BSD functions of the same names...
static int vmount_thread_main(int argc, char *argv[])
__EXPORT int vmount_main(int argc, char *argv[])
The main command function. 
virtual void print_status()=0
report status to stdout 
This defines the common API between an input and an output of the vmount driver. 
static bool get_params(ParameterHandles ¶m_handles, Parameters ¶ms)
__EXPORT param_t param_find(const char *name)
Look up a parameter by name. 
static void update_params(ParameterHandles ¶m_handles, Parameters ¶ms, bool &got_changes)
float pitch_scale
Scale factor for pitch channel (maps from angle in radians to actuator output in [-1,1]). 
void publish()
Publish _angle_outputs as a mount_orientation message. 
float roll_scale
Scale factor for roll channel (maps from angle in radians to actuator output in [-1,1]). 
class OutputBase Base class for all driver output classes 
static volatile bool thread_should_exit
float roll_offset
Offset for roll channel in radians. 
bool operator!=(const Parameters &p)
uint32_t param_t
Parameter handle.