2016-03-05 14:18:09 -04:00
|
|
|
#include "Sub.h"
|
|
|
|
|
2016-03-12 13:59:27 -04:00
|
|
|
// Functions that will handle joystick/gamepad input
|
2016-03-05 14:18:09 -04:00
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
|
2016-03-12 14:14:40 -04:00
|
|
|
// Anonymous namespace to hold variables used only in this file
|
2016-03-12 13:59:27 -04:00
|
|
|
namespace {
|
2017-02-03 17:33:27 -04:00
|
|
|
float cam_tilt = 1500.0;
|
2018-02-15 15:56:35 -04:00
|
|
|
float cam_pan = 1500.0;
|
2017-02-03 17:33:27 -04:00
|
|
|
int16_t lights1 = 1100;
|
|
|
|
int16_t lights2 = 1100;
|
|
|
|
int16_t rollTrim = 0;
|
|
|
|
int16_t pitchTrim = 0;
|
|
|
|
int16_t zTrim = 0;
|
|
|
|
int16_t xTrim = 0;
|
|
|
|
int16_t yTrim = 0;
|
|
|
|
int16_t video_switch = 1100;
|
|
|
|
int16_t x_last, y_last, z_last;
|
|
|
|
uint16_t buttons_prev;
|
2017-03-10 00:00:56 -04:00
|
|
|
|
|
|
|
// Servo control output channels
|
|
|
|
// TODO: Allow selecting output channels
|
|
|
|
const uint8_t SERVO_CHAN_1 = 9; // Pixhawk Aux1
|
|
|
|
const uint8_t SERVO_CHAN_2 = 10; // Pixhawk Aux2
|
|
|
|
const uint8_t SERVO_CHAN_3 = 11; // Pixhawk Aux3
|
2017-03-28 17:05:08 -03:00
|
|
|
|
|
|
|
uint8_t roll_pitch_flag = false; // Flag to adjust roll/pitch instead of forward/lateral
|
2016-11-23 17:22:30 -04:00
|
|
|
}
|
|
|
|
|
2017-02-03 17:33:27 -04:00
|
|
|
void Sub::init_joystick()
|
|
|
|
{
|
|
|
|
default_js_buttons();
|
2016-12-08 16:36:10 -04:00
|
|
|
|
2017-10-26 15:24:15 -03:00
|
|
|
lights1 = RC_Channels::rc_channel(8)->get_radio_min();
|
|
|
|
lights2 = RC_Channels::rc_channel(9)->get_radio_min();
|
|
|
|
|
2017-03-29 18:07:33 -03:00
|
|
|
set_mode(MANUAL, MODE_REASON_TX_COMMAND); // Initialize flight mode
|
2016-12-06 22:22:47 -04:00
|
|
|
|
2017-02-03 17:33:27 -04:00
|
|
|
if (g.numGainSettings < 1) {
|
|
|
|
g.numGainSettings.set_and_save(1);
|
|
|
|
}
|
2016-11-23 17:22:30 -04:00
|
|
|
|
2017-02-03 17:33:27 -04:00
|
|
|
if (g.numGainSettings == 1 || (g.gain_default < g.maxGain + 0.01 && g.gain_default > g.minGain - 0.01)) {
|
|
|
|
gain = constrain_float(g.gain_default, g.minGain, g.maxGain); // Use default gain parameter
|
2016-11-23 17:22:30 -04:00
|
|
|
} else {
|
2017-02-03 17:33:27 -04:00
|
|
|
// Use setting closest to average of minGain and maxGain
|
2016-11-23 17:22:30 -04:00
|
|
|
gain = g.minGain + (g.numGainSettings/2 - 1) * (g.maxGain - g.minGain) / (g.numGainSettings - 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
gain = constrain_float(gain, 0.1, 1.0);
|
2016-03-12 13:59:27 -04:00
|
|
|
}
|
|
|
|
|
2017-02-03 17:33:27 -04:00
|
|
|
void Sub::transform_manual_control_to_rc_override(int16_t x, int16_t y, int16_t z, int16_t r, uint16_t buttons)
|
|
|
|
{
|
|
|
|
|
|
|
|
float rpyScale = 0.4*gain; // Scale -1000-1000 to -400-400 with gain
|
|
|
|
float throttleScale = 0.8*gain*g.throttle_gain; // Scale 0-1000 to 0-800 times gain
|
|
|
|
int16_t rpyCenter = 1500;
|
|
|
|
int16_t throttleBase = 1500-500*throttleScale;
|
|
|
|
|
|
|
|
bool shift = false;
|
|
|
|
|
2018-02-15 15:56:35 -04:00
|
|
|
// Neutralize camera tilt and pan speed setpoint
|
2017-10-25 22:44:54 -03:00
|
|
|
cam_tilt = 1500;
|
2018-02-15 15:56:35 -04:00
|
|
|
cam_pan = 1500;
|
2017-10-25 22:44:54 -03:00
|
|
|
|
2017-10-25 22:43:23 -03:00
|
|
|
// Detect if any shift button is pressed
|
|
|
|
for (uint8_t i = 0 ; i < 16 ; i++) {
|
|
|
|
if ((buttons & (1 << i)) && get_button(i)->function() == JSButton::button_function_t::k_shift) {
|
|
|
|
shift = true;
|
2017-02-03 17:33:27 -04:00
|
|
|
}
|
2017-10-25 22:43:23 -03:00
|
|
|
}
|
2017-02-03 17:33:27 -04:00
|
|
|
|
2017-10-25 22:43:23 -03:00
|
|
|
// Act if button is pressed
|
|
|
|
// Only act upon pressing button and ignore holding. This provides compatibility with Taranis as joystick.
|
|
|
|
for (uint8_t i = 0 ; i < 16 ; i++) {
|
|
|
|
if ((buttons & (1 << i))) {
|
|
|
|
handle_jsbutton_press(i,shift,(buttons_prev & (1 << i)));
|
2017-11-22 17:01:06 -04:00
|
|
|
// buttonDebounce = tnow_ms;
|
|
|
|
} else if (buttons_prev & (1 << i)) {
|
|
|
|
handle_jsbutton_release(i, shift);
|
2017-10-25 22:43:23 -03:00
|
|
|
}
|
2017-02-03 17:33:27 -04:00
|
|
|
}
|
|
|
|
|
2017-10-25 22:43:23 -03:00
|
|
|
buttons_prev = buttons;
|
|
|
|
|
2017-09-29 19:07:44 -03:00
|
|
|
// attitude mode:
|
|
|
|
if (roll_pitch_flag == 1) {
|
|
|
|
// adjust roll/pitch trim with joystick input instead of forward/lateral
|
|
|
|
pitchTrim = -x * rpyScale;
|
|
|
|
rollTrim = y * rpyScale;
|
2017-03-28 17:05:08 -03:00
|
|
|
}
|
|
|
|
|
2018-05-29 03:26:16 -03:00
|
|
|
uint32_t tnow = AP_HAL::millis();
|
2017-09-29 19:07:44 -03:00
|
|
|
|
2018-05-29 03:26:16 -03:00
|
|
|
RC_Channels::set_override(0, constrain_int16(pitchTrim + rpyCenter,1100,1900), tnow); // pitch
|
|
|
|
RC_Channels::set_override(1, constrain_int16(rollTrim + rpyCenter,1100,1900), tnow); // roll
|
|
|
|
|
|
|
|
RC_Channels::set_override(2, constrain_int16((z+zTrim)*throttleScale+throttleBase,1100,1900), tnow); // throttle
|
|
|
|
RC_Channels::set_override(3, constrain_int16(r*rpyScale+rpyCenter,1100,1900), tnow); // yaw
|
2017-03-28 17:05:08 -03:00
|
|
|
|
2017-09-29 19:07:44 -03:00
|
|
|
// maneuver mode:
|
|
|
|
if (roll_pitch_flag == 0) {
|
2017-03-28 17:05:08 -03:00
|
|
|
// adjust forward and lateral with joystick input instead of roll and pitch
|
2018-05-29 03:26:16 -03:00
|
|
|
RC_Channels::set_override(4, constrain_int16((x+xTrim)*rpyScale+rpyCenter,1100,1900), tnow); // forward for ROV
|
|
|
|
RC_Channels::set_override(5, constrain_int16((y+yTrim)*rpyScale+rpyCenter,1100,1900), tnow); // lateral for ROV
|
2017-03-28 17:05:08 -03:00
|
|
|
} else {
|
|
|
|
// neutralize forward and lateral input while we are adjusting roll and pitch
|
2018-05-29 03:26:16 -03:00
|
|
|
RC_Channels::set_override(4, constrain_int16(xTrim*rpyScale+rpyCenter,1100,1900), tnow); // forward for ROV
|
|
|
|
RC_Channels::set_override(5, constrain_int16(yTrim*rpyScale+rpyCenter,1100,1900), tnow); // lateral for ROV
|
2017-03-28 17:05:08 -03:00
|
|
|
}
|
|
|
|
|
2018-05-29 03:26:16 -03:00
|
|
|
RC_Channels::set_override(6, cam_pan, tnow); // camera pan
|
|
|
|
RC_Channels::set_override(7, cam_tilt, tnow); // camera tilt
|
|
|
|
RC_Channels::set_override(8, lights1, tnow); // lights 1
|
|
|
|
RC_Channels::set_override(9, lights2, tnow); // lights 2
|
|
|
|
RC_Channels::set_override(10, video_switch, tnow); // video switch
|
2017-02-03 17:33:27 -04:00
|
|
|
|
|
|
|
// Store old x, y, z values for use in input hold logic
|
|
|
|
x_last = x;
|
|
|
|
y_last = y;
|
|
|
|
z_last = z;
|
2016-03-12 11:15:18 -04:00
|
|
|
}
|
|
|
|
|
2017-02-03 17:33:27 -04:00
|
|
|
void Sub::handle_jsbutton_press(uint8_t button, bool shift, bool held)
|
|
|
|
{
|
|
|
|
// Act based on the function assigned to this button
|
|
|
|
switch (get_button(button)->function(shift)) {
|
|
|
|
case JSButton::button_function_t::k_arm_toggle:
|
|
|
|
if (motors.armed()) {
|
|
|
|
init_disarm_motors();
|
|
|
|
} else {
|
2019-03-07 00:02:12 -04:00
|
|
|
init_arm_motors(AP_Arming::Method::MAVLINK);
|
2017-02-03 17:33:27 -04:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case JSButton::button_function_t::k_arm:
|
2019-03-07 00:02:12 -04:00
|
|
|
init_arm_motors(AP_Arming::Method::MAVLINK);
|
2017-02-03 17:33:27 -04:00
|
|
|
break;
|
|
|
|
case JSButton::button_function_t::k_disarm:
|
|
|
|
init_disarm_motors();
|
|
|
|
break;
|
2017-03-29 18:07:33 -03:00
|
|
|
|
|
|
|
case JSButton::button_function_t::k_mode_manual:
|
|
|
|
set_mode(MANUAL, MODE_REASON_TX_COMMAND);
|
|
|
|
break;
|
|
|
|
case JSButton::button_function_t::k_mode_stabilize:
|
|
|
|
set_mode(STABILIZE, MODE_REASON_TX_COMMAND);
|
2017-02-03 17:33:27 -04:00
|
|
|
break;
|
2017-03-29 18:07:33 -03:00
|
|
|
case JSButton::button_function_t::k_mode_depth_hold:
|
|
|
|
set_mode(ALT_HOLD, MODE_REASON_TX_COMMAND);
|
2017-02-03 17:33:27 -04:00
|
|
|
break;
|
2017-03-29 18:07:33 -03:00
|
|
|
case JSButton::button_function_t::k_mode_auto:
|
|
|
|
set_mode(AUTO, MODE_REASON_TX_COMMAND);
|
2017-02-03 17:33:27 -04:00
|
|
|
break;
|
2017-03-29 18:07:33 -03:00
|
|
|
case JSButton::button_function_t::k_mode_guided:
|
|
|
|
set_mode(GUIDED, MODE_REASON_TX_COMMAND);
|
2017-02-03 17:33:27 -04:00
|
|
|
break;
|
2017-03-29 18:07:33 -03:00
|
|
|
case JSButton::button_function_t::k_mode_circle:
|
|
|
|
set_mode(CIRCLE, MODE_REASON_TX_COMMAND);
|
2017-02-03 17:33:27 -04:00
|
|
|
break;
|
2017-03-29 18:07:33 -03:00
|
|
|
case JSButton::button_function_t::k_mode_acro:
|
|
|
|
set_mode(ACRO, MODE_REASON_TX_COMMAND);
|
2017-02-03 17:33:27 -04:00
|
|
|
break;
|
2017-03-29 18:07:33 -03:00
|
|
|
case JSButton::button_function_t::k_mode_poshold:
|
|
|
|
set_mode(POSHOLD, MODE_REASON_TX_COMMAND);
|
2017-02-03 17:33:27 -04:00
|
|
|
break;
|
2017-03-29 18:07:33 -03:00
|
|
|
|
2017-02-03 17:33:27 -04:00
|
|
|
case JSButton::button_function_t::k_mount_center:
|
2018-04-20 09:41:04 -03:00
|
|
|
#if MOUNT == ENABLED
|
2017-10-25 22:44:54 -03:00
|
|
|
camera_mount.set_angle_targets(0, 0, 0);
|
|
|
|
// for some reason the call to set_angle_targets changes the mode to mavlink targeting!
|
|
|
|
camera_mount.set_mode(MAV_MOUNT_MODE_RC_TARGETING);
|
2018-04-20 09:41:04 -03:00
|
|
|
#endif
|
2017-10-25 22:44:54 -03:00
|
|
|
break;
|
|
|
|
case JSButton::button_function_t::k_mount_tilt_up:
|
|
|
|
cam_tilt = 1900;
|
|
|
|
break;
|
|
|
|
case JSButton::button_function_t::k_mount_tilt_down:
|
|
|
|
cam_tilt = 1100;
|
2017-02-03 17:33:27 -04:00
|
|
|
break;
|
|
|
|
case JSButton::button_function_t::k_camera_trigger:
|
|
|
|
break;
|
|
|
|
case JSButton::button_function_t::k_camera_source_toggle:
|
|
|
|
if (!held) {
|
|
|
|
static bool video_toggle = false;
|
|
|
|
video_toggle = !video_toggle;
|
|
|
|
if (video_toggle) {
|
|
|
|
video_switch = 1900;
|
2017-07-08 22:51:41 -03:00
|
|
|
gcs().send_text(MAV_SEVERITY_INFO,"Video Toggle: Source 2");
|
2017-02-03 17:33:27 -04:00
|
|
|
} else {
|
|
|
|
video_switch = 1100;
|
2017-07-08 22:51:41 -03:00
|
|
|
gcs().send_text(MAV_SEVERITY_INFO,"Video Toggle: Source 1");
|
2017-02-03 17:33:27 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case JSButton::button_function_t::k_mount_pan_right:
|
2018-02-15 15:56:35 -04:00
|
|
|
cam_pan = 1900;
|
2017-02-03 17:33:27 -04:00
|
|
|
break;
|
|
|
|
case JSButton::button_function_t::k_mount_pan_left:
|
2018-02-15 15:56:35 -04:00
|
|
|
cam_pan = 1100;
|
2017-02-03 17:33:27 -04:00
|
|
|
break;
|
|
|
|
case JSButton::button_function_t::k_lights1_cycle:
|
|
|
|
if (!held) {
|
|
|
|
static bool increasing = true;
|
2017-10-26 15:24:15 -03:00
|
|
|
RC_Channel* chan = RC_Channels::rc_channel(8);
|
|
|
|
uint16_t min = chan->get_radio_min();
|
|
|
|
uint16_t max = chan->get_radio_max();
|
2017-10-26 16:42:56 -03:00
|
|
|
uint16_t step = (max - min) / g.lights_steps;
|
2017-02-03 17:33:27 -04:00
|
|
|
if (increasing) {
|
2017-10-26 16:42:56 -03:00
|
|
|
lights1 = constrain_float(lights1 + step, min, max);
|
2017-02-03 17:33:27 -04:00
|
|
|
} else {
|
2017-10-26 16:42:56 -03:00
|
|
|
lights1 = constrain_float(lights1 - step, min, max);
|
2017-02-03 17:33:27 -04:00
|
|
|
}
|
2017-10-26 15:24:15 -03:00
|
|
|
if (lights1 >= max || lights1 <= min) {
|
2017-02-03 17:33:27 -04:00
|
|
|
increasing = !increasing;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case JSButton::button_function_t::k_lights1_brighter:
|
|
|
|
if (!held) {
|
2017-10-26 15:24:15 -03:00
|
|
|
RC_Channel* chan = RC_Channels::rc_channel(8);
|
|
|
|
uint16_t min = chan->get_radio_min();
|
|
|
|
uint16_t max = chan->get_radio_max();
|
2017-10-26 16:42:56 -03:00
|
|
|
uint16_t step = (max - min) / g.lights_steps;
|
|
|
|
lights1 = constrain_float(lights1 + step, min, max);
|
2017-02-03 17:33:27 -04:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case JSButton::button_function_t::k_lights1_dimmer:
|
|
|
|
if (!held) {
|
2017-10-26 15:24:15 -03:00
|
|
|
RC_Channel* chan = RC_Channels::rc_channel(8);
|
|
|
|
uint16_t min = chan->get_radio_min();
|
|
|
|
uint16_t max = chan->get_radio_max();
|
2017-10-26 16:42:56 -03:00
|
|
|
uint16_t step = (max - min) / g.lights_steps;
|
|
|
|
lights1 = constrain_float(lights1 - step, min, max);
|
2017-02-03 17:33:27 -04:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case JSButton::button_function_t::k_lights2_cycle:
|
|
|
|
if (!held) {
|
|
|
|
static bool increasing = true;
|
2017-10-26 15:24:15 -03:00
|
|
|
RC_Channel* chan = RC_Channels::rc_channel(9);
|
|
|
|
uint16_t min = chan->get_radio_min();
|
|
|
|
uint16_t max = chan->get_radio_max();
|
2017-10-26 16:42:56 -03:00
|
|
|
uint16_t step = (max - min) / g.lights_steps;
|
2017-02-03 17:33:27 -04:00
|
|
|
if (increasing) {
|
2017-10-26 16:42:56 -03:00
|
|
|
lights2 = constrain_float(lights2 + step, min, max);
|
2017-02-03 17:33:27 -04:00
|
|
|
} else {
|
2017-10-26 16:42:56 -03:00
|
|
|
lights2 = constrain_float(lights2 - step, min, max);
|
2017-02-03 17:33:27 -04:00
|
|
|
}
|
2017-10-26 15:24:15 -03:00
|
|
|
if (lights2 >= max || lights2 <= min) {
|
2017-02-03 17:33:27 -04:00
|
|
|
increasing = !increasing;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case JSButton::button_function_t::k_lights2_brighter:
|
|
|
|
if (!held) {
|
2017-10-26 15:24:15 -03:00
|
|
|
RC_Channel* chan = RC_Channels::rc_channel(9);
|
|
|
|
uint16_t min = chan->get_radio_min();
|
|
|
|
uint16_t max = chan->get_radio_max();
|
2017-10-26 16:42:56 -03:00
|
|
|
uint16_t step = (max - min) / g.lights_steps;
|
|
|
|
lights2 = constrain_float(lights2 + step, min, max);
|
2017-02-03 17:33:27 -04:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case JSButton::button_function_t::k_lights2_dimmer:
|
|
|
|
if (!held) {
|
2017-10-26 15:24:15 -03:00
|
|
|
RC_Channel* chan = RC_Channels::rc_channel(9);
|
|
|
|
uint16_t min = chan->get_radio_min();
|
|
|
|
uint16_t max = chan->get_radio_max();
|
2017-10-26 16:42:56 -03:00
|
|
|
uint16_t step = (max - min) / g.lights_steps;
|
|
|
|
lights2 = constrain_float(lights2 - step, min, max);
|
2017-02-03 17:33:27 -04:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case JSButton::button_function_t::k_gain_toggle:
|
|
|
|
if (!held) {
|
|
|
|
static bool lowGain = false;
|
|
|
|
lowGain = !lowGain;
|
|
|
|
if (lowGain) {
|
|
|
|
gain = 0.5f;
|
|
|
|
} else {
|
|
|
|
gain = 1.0f;
|
|
|
|
}
|
2017-07-08 22:51:41 -03:00
|
|
|
gcs().send_text(MAV_SEVERITY_INFO,"#Gain: %2.0f%%",(double)gain*100);
|
2017-02-03 17:33:27 -04:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case JSButton::button_function_t::k_gain_inc:
|
|
|
|
if (!held) {
|
|
|
|
// check that our gain parameters are in correct range, update in eeprom and notify gcs if needed
|
|
|
|
g.minGain.set_and_save(constrain_float(g.minGain, 0.10, 0.80));
|
|
|
|
g.maxGain.set_and_save(constrain_float(g.maxGain, g.minGain, 1.0));
|
|
|
|
g.numGainSettings.set_and_save(constrain_int16(g.numGainSettings, 1, 10));
|
|
|
|
|
|
|
|
if (g.numGainSettings == 1) {
|
|
|
|
gain = constrain_float(g.gain_default, g.minGain, g.maxGain);
|
|
|
|
} else {
|
|
|
|
gain = constrain_float(gain + (g.maxGain-g.minGain)/(g.numGainSettings-1), g.minGain, g.maxGain);
|
|
|
|
}
|
|
|
|
|
2017-07-08 22:51:41 -03:00
|
|
|
gcs().send_text(MAV_SEVERITY_INFO,"#Gain is %2.0f%%",(double)gain*100);
|
2017-02-03 17:33:27 -04:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case JSButton::button_function_t::k_gain_dec:
|
|
|
|
if (!held) {
|
|
|
|
// check that our gain parameters are in correct range, update in eeprom and notify gcs if needed
|
|
|
|
g.minGain.set_and_save(constrain_float(g.minGain, 0.10, 0.80));
|
|
|
|
g.maxGain.set_and_save(constrain_float(g.maxGain, g.minGain, 1.0));
|
|
|
|
g.numGainSettings.set_and_save(constrain_int16(g.numGainSettings, 1, 10));
|
|
|
|
|
|
|
|
if (g.numGainSettings == 1) {
|
|
|
|
gain = constrain_float(g.gain_default, g.minGain, g.maxGain);
|
|
|
|
} else {
|
|
|
|
gain = constrain_float(gain - (g.maxGain-g.minGain)/(g.numGainSettings-1), g.minGain, g.maxGain);
|
|
|
|
}
|
|
|
|
|
2017-07-08 22:51:41 -03:00
|
|
|
gcs().send_text(MAV_SEVERITY_INFO,"#Gain is %2.0f%%",(double)gain*100);
|
2017-02-03 17:33:27 -04:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case JSButton::button_function_t::k_trim_roll_inc:
|
|
|
|
rollTrim = constrain_float(rollTrim+10,-200,200);
|
|
|
|
break;
|
|
|
|
case JSButton::button_function_t::k_trim_roll_dec:
|
|
|
|
rollTrim = constrain_float(rollTrim-10,-200,200);
|
|
|
|
break;
|
|
|
|
case JSButton::button_function_t::k_trim_pitch_inc:
|
|
|
|
pitchTrim = constrain_float(pitchTrim+10,-200,200);
|
|
|
|
break;
|
|
|
|
case JSButton::button_function_t::k_trim_pitch_dec:
|
|
|
|
pitchTrim = constrain_float(pitchTrim-10,-200,200);
|
|
|
|
break;
|
2017-08-19 20:44:36 -03:00
|
|
|
case JSButton::button_function_t::k_input_hold_set:
|
2017-09-18 16:30:48 -03:00
|
|
|
if(!motors.armed()) {
|
|
|
|
break;
|
|
|
|
}
|
2017-02-03 17:33:27 -04:00
|
|
|
if (!held) {
|
2017-10-20 17:02:50 -03:00
|
|
|
zTrim = abs(z_last-500) > 50 ? z_last-500 : 0;
|
|
|
|
xTrim = abs(x_last) > 50 ? x_last : 0;
|
|
|
|
yTrim = abs(y_last) > 50 ? y_last : 0;
|
2017-09-18 16:56:04 -03:00
|
|
|
bool input_hold_engaged_last = input_hold_engaged;
|
2017-10-20 17:02:50 -03:00
|
|
|
input_hold_engaged = zTrim || xTrim || yTrim;
|
2017-09-18 16:56:04 -03:00
|
|
|
if (input_hold_engaged) {
|
|
|
|
gcs().send_text(MAV_SEVERITY_INFO,"#Input Hold Set");
|
|
|
|
} else if (input_hold_engaged_last) {
|
|
|
|
gcs().send_text(MAV_SEVERITY_INFO,"#Input Hold Disabled");
|
|
|
|
}
|
2017-02-03 17:33:27 -04:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case JSButton::button_function_t::k_relay_1_on:
|
2017-02-21 17:15:24 -04:00
|
|
|
relay.on(0);
|
2017-02-03 17:33:27 -04:00
|
|
|
break;
|
|
|
|
case JSButton::button_function_t::k_relay_1_off:
|
2017-02-21 17:15:24 -04:00
|
|
|
relay.off(0);
|
2017-02-03 17:33:27 -04:00
|
|
|
break;
|
|
|
|
case JSButton::button_function_t::k_relay_1_toggle:
|
2017-02-21 17:15:24 -04:00
|
|
|
if (!held) {
|
|
|
|
relay.toggle(0);
|
|
|
|
}
|
2017-02-03 17:33:27 -04:00
|
|
|
break;
|
2017-11-22 17:01:06 -04:00
|
|
|
case JSButton::button_function_t::k_relay_1_momentary:
|
|
|
|
if (!held) {
|
|
|
|
relay.on(0);
|
|
|
|
}
|
|
|
|
break;
|
2017-02-03 17:33:27 -04:00
|
|
|
case JSButton::button_function_t::k_relay_2_on:
|
2017-02-21 17:15:24 -04:00
|
|
|
relay.on(1);
|
2017-02-03 17:33:27 -04:00
|
|
|
break;
|
|
|
|
case JSButton::button_function_t::k_relay_2_off:
|
2017-02-21 17:15:24 -04:00
|
|
|
relay.off(1);
|
2017-02-03 17:33:27 -04:00
|
|
|
break;
|
|
|
|
case JSButton::button_function_t::k_relay_2_toggle:
|
2017-02-21 17:15:24 -04:00
|
|
|
if (!held) {
|
|
|
|
relay.toggle(1);
|
|
|
|
}
|
2017-02-03 17:33:27 -04:00
|
|
|
break;
|
2017-11-22 17:01:06 -04:00
|
|
|
case JSButton::button_function_t::k_relay_2_momentary:
|
|
|
|
if (!held) {
|
|
|
|
relay.on(1);
|
|
|
|
}
|
|
|
|
break;
|
2017-10-26 13:32:56 -03:00
|
|
|
case JSButton::button_function_t::k_relay_3_on:
|
|
|
|
relay.on(2);
|
|
|
|
break;
|
|
|
|
case JSButton::button_function_t::k_relay_3_off:
|
|
|
|
relay.off(2);
|
|
|
|
break;
|
|
|
|
case JSButton::button_function_t::k_relay_3_toggle:
|
|
|
|
if (!held) {
|
|
|
|
relay.toggle(2);
|
|
|
|
}
|
|
|
|
break;
|
2017-11-22 17:01:06 -04:00
|
|
|
case JSButton::button_function_t::k_relay_3_momentary:
|
|
|
|
if (!held) {
|
|
|
|
relay.on(2);
|
|
|
|
}
|
|
|
|
break;
|
2017-10-26 13:32:56 -03:00
|
|
|
case JSButton::button_function_t::k_relay_4_on:
|
|
|
|
relay.on(3);
|
|
|
|
break;
|
|
|
|
case JSButton::button_function_t::k_relay_4_off:
|
|
|
|
relay.off(3);
|
|
|
|
break;
|
|
|
|
case JSButton::button_function_t::k_relay_4_toggle:
|
|
|
|
if (!held) {
|
|
|
|
relay.toggle(3);
|
|
|
|
}
|
|
|
|
break;
|
2017-11-22 17:01:06 -04:00
|
|
|
case JSButton::button_function_t::k_relay_4_momentary:
|
|
|
|
if (!held) {
|
|
|
|
relay.on(3);
|
|
|
|
}
|
|
|
|
break;
|
2017-03-10 00:00:56 -04:00
|
|
|
|
|
|
|
////////////////////////////////////////////////
|
|
|
|
// Servo functions
|
|
|
|
// TODO: initialize
|
|
|
|
case JSButton::button_function_t::k_servo_1_inc:
|
|
|
|
{
|
|
|
|
SRV_Channel* chan = SRV_Channels::srv_channel(SERVO_CHAN_1 - 1); // 0-indexed
|
|
|
|
uint16_t pwm_out = hal.rcout->read(SERVO_CHAN_1 - 1); // 0-indexed
|
|
|
|
pwm_out = constrain_int16(pwm_out + 50, chan->get_output_min(), chan->get_output_max());
|
|
|
|
ServoRelayEvents.do_set_servo(SERVO_CHAN_1, pwm_out); // 1-indexed
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case JSButton::button_function_t::k_servo_1_dec:
|
|
|
|
{
|
|
|
|
SRV_Channel* chan = SRV_Channels::srv_channel(SERVO_CHAN_1 - 1); // 0-indexed
|
|
|
|
uint16_t pwm_out = hal.rcout->read(SERVO_CHAN_1 - 1); // 0-indexed
|
|
|
|
pwm_out = constrain_int16(pwm_out - 50, chan->get_output_min(), chan->get_output_max());
|
|
|
|
ServoRelayEvents.do_set_servo(SERVO_CHAN_1, pwm_out); // 1-indexed
|
|
|
|
}
|
|
|
|
break;
|
2017-03-28 01:28:06 -03:00
|
|
|
case JSButton::button_function_t::k_servo_1_min:
|
2017-11-22 17:40:22 -04:00
|
|
|
case JSButton::button_function_t::k_servo_1_min_momentary:
|
2017-03-28 01:28:06 -03:00
|
|
|
{
|
|
|
|
SRV_Channel* chan = SRV_Channels::srv_channel(SERVO_CHAN_1 - 1); // 0-indexed
|
|
|
|
ServoRelayEvents.do_set_servo(SERVO_CHAN_1, chan->get_output_min()); // 1-indexed
|
|
|
|
}
|
|
|
|
break;
|
2017-11-27 17:19:20 -04:00
|
|
|
case JSButton::button_function_t::k_servo_1_min_toggle:
|
|
|
|
if(!held) {
|
|
|
|
SRV_Channel* chan = SRV_Channels::srv_channel(SERVO_CHAN_1 - 1); // 0-indexed
|
|
|
|
if(chan->get_output_pwm() != chan->get_output_min()) {
|
|
|
|
ServoRelayEvents.do_set_servo(SERVO_CHAN_1, chan->get_output_min()); // 1-indexed
|
|
|
|
} else {
|
|
|
|
ServoRelayEvents.do_set_servo(SERVO_CHAN_1, chan->get_trim()); // 1-indexed
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
2017-03-28 01:28:06 -03:00
|
|
|
case JSButton::button_function_t::k_servo_1_max:
|
2017-11-22 17:40:22 -04:00
|
|
|
case JSButton::button_function_t::k_servo_1_max_momentary:
|
2017-03-28 01:28:06 -03:00
|
|
|
{
|
|
|
|
SRV_Channel* chan = SRV_Channels::srv_channel(SERVO_CHAN_1 - 1); // 0-indexed
|
|
|
|
ServoRelayEvents.do_set_servo(SERVO_CHAN_1, chan->get_output_max()); // 1-indexed
|
|
|
|
}
|
|
|
|
break;
|
2017-11-27 17:19:20 -04:00
|
|
|
case JSButton::button_function_t::k_servo_1_max_toggle:
|
|
|
|
if(!held) {
|
|
|
|
SRV_Channel* chan = SRV_Channels::srv_channel(SERVO_CHAN_1 - 1); // 0-indexed
|
|
|
|
if(chan->get_output_pwm() != chan->get_output_max()) {
|
|
|
|
ServoRelayEvents.do_set_servo(SERVO_CHAN_1, chan->get_output_max()); // 1-indexed
|
|
|
|
} else {
|
|
|
|
ServoRelayEvents.do_set_servo(SERVO_CHAN_1, chan->get_trim()); // 1-indexed
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
2017-03-10 00:00:56 -04:00
|
|
|
case JSButton::button_function_t::k_servo_1_center:
|
|
|
|
{
|
|
|
|
SRV_Channel* chan = SRV_Channels::srv_channel(SERVO_CHAN_1 - 1); // 0-indexed
|
2017-03-28 01:28:06 -03:00
|
|
|
ServoRelayEvents.do_set_servo(SERVO_CHAN_1, chan->get_trim()); // 1-indexed
|
2017-03-10 00:00:56 -04:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case JSButton::button_function_t::k_servo_2_inc:
|
|
|
|
{
|
|
|
|
SRV_Channel* chan = SRV_Channels::srv_channel(SERVO_CHAN_2 - 1); // 0-indexed
|
|
|
|
uint16_t pwm_out = hal.rcout->read(SERVO_CHAN_2 - 1); // 0-indexed
|
|
|
|
pwm_out = constrain_int16(pwm_out + 50, chan->get_output_min(), chan->get_output_max());
|
|
|
|
ServoRelayEvents.do_set_servo(SERVO_CHAN_2, pwm_out); // 1-indexed
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case JSButton::button_function_t::k_servo_2_dec:
|
|
|
|
{
|
|
|
|
SRV_Channel* chan = SRV_Channels::srv_channel(SERVO_CHAN_2 - 1); // 0-indexed
|
|
|
|
uint16_t pwm_out = hal.rcout->read(SERVO_CHAN_2 - 1); // 0-indexed
|
|
|
|
pwm_out = constrain_int16(pwm_out - 50, chan->get_output_min(), chan->get_output_max());
|
|
|
|
ServoRelayEvents.do_set_servo(SERVO_CHAN_2, pwm_out); // 1-indexed
|
|
|
|
}
|
|
|
|
break;
|
2017-03-28 01:28:06 -03:00
|
|
|
case JSButton::button_function_t::k_servo_2_min:
|
2017-11-22 17:40:22 -04:00
|
|
|
case JSButton::button_function_t::k_servo_2_min_momentary:
|
2017-03-28 01:28:06 -03:00
|
|
|
{
|
|
|
|
SRV_Channel* chan = SRV_Channels::srv_channel(SERVO_CHAN_2 - 1); // 0-indexed
|
|
|
|
ServoRelayEvents.do_set_servo(SERVO_CHAN_2, chan->get_output_min()); // 1-indexed
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case JSButton::button_function_t::k_servo_2_max:
|
2017-11-22 17:40:22 -04:00
|
|
|
case JSButton::button_function_t::k_servo_2_max_momentary:
|
2017-03-28 01:28:06 -03:00
|
|
|
{
|
|
|
|
SRV_Channel* chan = SRV_Channels::srv_channel(SERVO_CHAN_2 - 1); // 0-indexed
|
|
|
|
ServoRelayEvents.do_set_servo(SERVO_CHAN_2, chan->get_output_max()); // 1-indexed
|
|
|
|
}
|
|
|
|
break;
|
2017-03-10 00:00:56 -04:00
|
|
|
case JSButton::button_function_t::k_servo_2_center:
|
|
|
|
{
|
|
|
|
SRV_Channel* chan = SRV_Channels::srv_channel(SERVO_CHAN_2 - 1); // 0-indexed
|
2017-03-28 01:28:06 -03:00
|
|
|
ServoRelayEvents.do_set_servo(SERVO_CHAN_2, chan->get_trim()); // 1-indexed
|
2017-03-10 00:00:56 -04:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case JSButton::button_function_t::k_servo_3_inc:
|
|
|
|
{
|
|
|
|
SRV_Channel* chan = SRV_Channels::srv_channel(SERVO_CHAN_3 - 1); // 0-indexed
|
|
|
|
uint16_t pwm_out = hal.rcout->read(SERVO_CHAN_3 - 1); // 0-indexed
|
|
|
|
pwm_out = constrain_int16(pwm_out + 50, chan->get_output_min(), chan->get_output_max());
|
|
|
|
ServoRelayEvents.do_set_servo(SERVO_CHAN_3, pwm_out); // 1-indexed
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case JSButton::button_function_t::k_servo_3_dec:
|
|
|
|
{
|
|
|
|
SRV_Channel* chan = SRV_Channels::srv_channel(SERVO_CHAN_3 - 1); // 0-indexed
|
|
|
|
uint16_t pwm_out = hal.rcout->read(SERVO_CHAN_3 - 1); // 0-indexed
|
|
|
|
pwm_out = constrain_int16(pwm_out - 50, chan->get_output_min(), chan->get_output_max());
|
|
|
|
ServoRelayEvents.do_set_servo(SERVO_CHAN_3, pwm_out); // 1-indexed
|
|
|
|
}
|
|
|
|
break;
|
2017-03-28 01:28:06 -03:00
|
|
|
case JSButton::button_function_t::k_servo_3_min:
|
2017-11-22 17:40:22 -04:00
|
|
|
case JSButton::button_function_t::k_servo_3_min_momentary:
|
2017-03-28 01:28:06 -03:00
|
|
|
{
|
|
|
|
SRV_Channel* chan = SRV_Channels::srv_channel(SERVO_CHAN_3 - 1); // 0-indexed
|
|
|
|
ServoRelayEvents.do_set_servo(SERVO_CHAN_3, chan->get_output_min()); // 1-indexed
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case JSButton::button_function_t::k_servo_3_max:
|
2017-11-22 17:40:22 -04:00
|
|
|
case JSButton::button_function_t::k_servo_3_max_momentary:
|
2017-03-28 01:28:06 -03:00
|
|
|
{
|
|
|
|
SRV_Channel* chan = SRV_Channels::srv_channel(SERVO_CHAN_3 - 1); // 0-indexed
|
|
|
|
ServoRelayEvents.do_set_servo(SERVO_CHAN_3, chan->get_output_max()); // 1-indexed
|
|
|
|
}
|
|
|
|
break;
|
2017-03-10 00:00:56 -04:00
|
|
|
case JSButton::button_function_t::k_servo_3_center:
|
|
|
|
{
|
|
|
|
SRV_Channel* chan = SRV_Channels::srv_channel(SERVO_CHAN_3 - 1); // 0-indexed
|
2017-03-28 01:28:06 -03:00
|
|
|
ServoRelayEvents.do_set_servo(SERVO_CHAN_3, chan->get_trim()); // 1-indexed
|
2017-03-10 00:00:56 -04:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2017-03-28 17:05:08 -03:00
|
|
|
case JSButton::button_function_t::k_roll_pitch_toggle:
|
|
|
|
if (!held) {
|
|
|
|
roll_pitch_flag = !roll_pitch_flag;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2017-02-03 17:33:27 -04:00
|
|
|
case JSButton::button_function_t::k_custom_1:
|
|
|
|
// Not implemented
|
|
|
|
break;
|
|
|
|
case JSButton::button_function_t::k_custom_2:
|
|
|
|
// Not implemented
|
|
|
|
break;
|
|
|
|
case JSButton::button_function_t::k_custom_3:
|
|
|
|
// Not implemented
|
|
|
|
break;
|
|
|
|
case JSButton::button_function_t::k_custom_4:
|
|
|
|
// Not implemented
|
|
|
|
break;
|
|
|
|
case JSButton::button_function_t::k_custom_5:
|
|
|
|
// Not implemented
|
|
|
|
break;
|
|
|
|
case JSButton::button_function_t::k_custom_6:
|
|
|
|
// Not implemented
|
|
|
|
break;
|
|
|
|
}
|
2016-03-12 13:59:27 -04:00
|
|
|
}
|
2016-03-12 14:14:40 -04:00
|
|
|
|
2017-11-22 17:01:06 -04:00
|
|
|
void Sub::handle_jsbutton_release(uint8_t button, bool shift) {
|
|
|
|
|
|
|
|
// Act based on the function assigned to this button
|
|
|
|
switch (get_button(button)->function(shift)) {
|
|
|
|
case JSButton::button_function_t::k_relay_1_momentary:
|
|
|
|
relay.off(0);
|
|
|
|
break;
|
|
|
|
case JSButton::button_function_t::k_relay_2_momentary:
|
|
|
|
relay.off(1);
|
|
|
|
break;
|
|
|
|
case JSButton::button_function_t::k_relay_3_momentary:
|
|
|
|
relay.off(2);
|
|
|
|
break;
|
|
|
|
case JSButton::button_function_t::k_relay_4_momentary:
|
|
|
|
relay.off(3);
|
|
|
|
break;
|
2017-11-22 17:40:22 -04:00
|
|
|
case JSButton::button_function_t::k_servo_1_min_momentary:
|
|
|
|
case JSButton::button_function_t::k_servo_1_max_momentary:
|
|
|
|
{
|
|
|
|
SRV_Channel* chan = SRV_Channels::srv_channel(SERVO_CHAN_1 - 1); // 0-indexed
|
|
|
|
ServoRelayEvents.do_set_servo(SERVO_CHAN_1, chan->get_trim()); // 1-indexed
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case JSButton::button_function_t::k_servo_2_min_momentary:
|
|
|
|
case JSButton::button_function_t::k_servo_2_max_momentary:
|
|
|
|
{
|
|
|
|
SRV_Channel* chan = SRV_Channels::srv_channel(SERVO_CHAN_2 - 1); // 0-indexed
|
|
|
|
ServoRelayEvents.do_set_servo(SERVO_CHAN_2, chan->get_trim()); // 1-indexed
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case JSButton::button_function_t::k_servo_3_min_momentary:
|
|
|
|
case JSButton::button_function_t::k_servo_3_max_momentary:
|
|
|
|
{
|
|
|
|
SRV_Channel* chan = SRV_Channels::srv_channel(SERVO_CHAN_3 - 1); // 0-indexed
|
|
|
|
ServoRelayEvents.do_set_servo(SERVO_CHAN_3, chan->get_trim()); // 1-indexed
|
|
|
|
}
|
|
|
|
break;
|
2017-11-22 17:01:06 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-02-03 17:33:27 -04:00
|
|
|
JSButton* Sub::get_button(uint8_t index)
|
|
|
|
{
|
|
|
|
// Help to access appropriate parameter
|
|
|
|
switch (index) {
|
|
|
|
case 0:
|
|
|
|
return &g.jbtn_0;
|
|
|
|
case 1:
|
|
|
|
return &g.jbtn_1;
|
|
|
|
case 2:
|
|
|
|
return &g.jbtn_2;
|
|
|
|
case 3:
|
|
|
|
return &g.jbtn_3;
|
|
|
|
case 4:
|
|
|
|
return &g.jbtn_4;
|
|
|
|
case 5:
|
|
|
|
return &g.jbtn_5;
|
|
|
|
case 6:
|
|
|
|
return &g.jbtn_6;
|
|
|
|
case 7:
|
|
|
|
return &g.jbtn_7;
|
|
|
|
case 8:
|
|
|
|
return &g.jbtn_8;
|
|
|
|
case 9:
|
|
|
|
return &g.jbtn_9;
|
|
|
|
case 10:
|
|
|
|
return &g.jbtn_10;
|
|
|
|
case 11:
|
|
|
|
return &g.jbtn_11;
|
|
|
|
case 12:
|
|
|
|
return &g.jbtn_12;
|
|
|
|
case 13:
|
|
|
|
return &g.jbtn_13;
|
|
|
|
case 14:
|
|
|
|
return &g.jbtn_14;
|
|
|
|
case 15:
|
|
|
|
return &g.jbtn_15;
|
|
|
|
default:
|
|
|
|
return &g.jbtn_0;
|
|
|
|
}
|
2016-03-12 14:14:40 -04:00
|
|
|
}
|
2016-08-10 16:07:37 -03:00
|
|
|
|
2017-02-03 17:33:27 -04:00
|
|
|
void Sub::default_js_buttons()
|
|
|
|
{
|
|
|
|
JSButton::button_function_t defaults[16][2] = {
|
2017-04-16 16:48:35 -03:00
|
|
|
{JSButton::button_function_t::k_none, JSButton::button_function_t::k_none},
|
|
|
|
{JSButton::button_function_t::k_mode_manual, JSButton::button_function_t::k_none},
|
|
|
|
{JSButton::button_function_t::k_mode_depth_hold, JSButton::button_function_t::k_none},
|
|
|
|
{JSButton::button_function_t::k_mode_stabilize, JSButton::button_function_t::k_none},
|
2017-02-03 17:33:27 -04:00
|
|
|
|
|
|
|
{JSButton::button_function_t::k_disarm, JSButton::button_function_t::k_none},
|
|
|
|
{JSButton::button_function_t::k_shift, JSButton::button_function_t::k_none},
|
|
|
|
{JSButton::button_function_t::k_arm, JSButton::button_function_t::k_none},
|
|
|
|
{JSButton::button_function_t::k_mount_center, JSButton::button_function_t::k_none},
|
|
|
|
|
2017-08-19 20:44:36 -03:00
|
|
|
{JSButton::button_function_t::k_input_hold_set, JSButton::button_function_t::k_none},
|
2018-02-15 15:56:35 -04:00
|
|
|
{JSButton::button_function_t::k_mount_tilt_down, JSButton::button_function_t::k_mount_pan_left},
|
|
|
|
{JSButton::button_function_t::k_mount_tilt_up, JSButton::button_function_t::k_mount_pan_right},
|
2017-02-03 17:33:27 -04:00
|
|
|
{JSButton::button_function_t::k_gain_inc, JSButton::button_function_t::k_trim_pitch_dec},
|
|
|
|
|
|
|
|
{JSButton::button_function_t::k_gain_dec, JSButton::button_function_t::k_trim_pitch_inc},
|
|
|
|
{JSButton::button_function_t::k_lights1_dimmer, JSButton::button_function_t::k_trim_roll_dec},
|
|
|
|
{JSButton::button_function_t::k_lights1_brighter, JSButton::button_function_t::k_trim_roll_inc},
|
|
|
|
{JSButton::button_function_t::k_none, JSButton::button_function_t::k_none},
|
|
|
|
};
|
|
|
|
|
|
|
|
for (int i = 0; i < 16; i++) {
|
|
|
|
get_button(i)->set_default(defaults[i][0], defaults[i][1]);
|
|
|
|
}
|
2016-12-08 16:36:10 -04:00
|
|
|
}
|
2017-01-30 13:49:39 -04:00
|
|
|
|
2017-02-03 17:33:27 -04:00
|
|
|
void Sub::set_neutral_controls()
|
|
|
|
{
|
2018-05-29 03:26:16 -03:00
|
|
|
uint32_t tnow = AP_HAL::millis();
|
2017-01-30 13:49:39 -04:00
|
|
|
|
2017-04-16 19:22:08 -03:00
|
|
|
for (uint8_t i = 0; i < 6; i++) {
|
2018-05-29 03:26:16 -03:00
|
|
|
RC_Channels::set_override(i, 1500, tnow);
|
2017-02-03 17:33:27 -04:00
|
|
|
}
|
2017-01-30 13:49:39 -04:00
|
|
|
|
2017-04-16 19:22:08 -03:00
|
|
|
for (uint8_t i = 6; i < 11; i++) {
|
2018-05-29 03:26:16 -03:00
|
|
|
RC_Channels::set_override(i, 0xffff, tnow);
|
2017-02-03 17:33:27 -04:00
|
|
|
}
|
2017-01-30 13:49:39 -04:00
|
|
|
|
2017-10-31 11:23:31 -03:00
|
|
|
// Clear pitch/roll trim settings
|
|
|
|
pitchTrim = 0;
|
|
|
|
rollTrim = 0;
|
2017-01-30 13:49:39 -04:00
|
|
|
}
|
2017-09-18 15:42:53 -03:00
|
|
|
|
|
|
|
void Sub::clear_input_hold()
|
|
|
|
{
|
|
|
|
xTrim = 0;
|
|
|
|
yTrim = 0;
|
|
|
|
zTrim = 0;
|
|
|
|
input_hold_engaged = false;
|
|
|
|
}
|