diff --git a/msg/rc_channels.msg b/msg/rc_channels.msg index b040eefcc2..7b3dae4091 100644 --- a/msg/rc_channels.msg +++ b/msg/rc_channels.msg @@ -20,9 +20,7 @@ uint8 FUNCTION_PARAM_3_5 = 16 uint8 FUNCTION_KILLSWITCH = 17 uint8 FUNCTION_TRANSITION = 18 uint8 FUNCTION_GEAR = 19 -uint8 FUNCTION_ARMSWITCH = 2 - -uint8 FUNCTION_FLTBTN_SLOT_COUNT = 6 +uint8 FUNCTION_ARMSWITCH = 20 uint64 timestamp_last_valid # Timestamp of last valid RC signal float32[18] channels # Scaled to -1..1 (throttle: 0..1) diff --git a/src/modules/rc_update/params.c b/src/modules/rc_update/params.c index 5d25fb8b61..5b06376a84 100644 --- a/src/modules/rc_update/params.c +++ b/src/modules/rc_update/params.c @@ -1618,6 +1618,9 @@ PARAM_DEFINE_INT32(RC_TRIG1_CHAN, 0); /** * Which action the Trigger slot 1 triggers * + * The flight mode enums follow the convention defined in the commander_state.msg uORB message. + * Everything else (16 ~ ) is a non-flight-mode actions + * * @min -1 * @max 20 * @group Radio Trigger @@ -1626,7 +1629,7 @@ PARAM_DEFINE_INT32(RC_TRIG1_CHAN, 0); * @value 1 Altitude * @value 2 Position * @value 3 Mission - * @value 4 Hold + * @value 4 Loiter * @value 5 Return * @value 6 Acro * @value 7 Offboard @@ -1635,14 +1638,14 @@ PARAM_DEFINE_INT32(RC_TRIG1_CHAN, 0); * @value 11 Land * @value 12 Follow Me * @value 13 Precision Land - * @value 14 Return - * @value 15 Loiter - * @value 16 Offboard - * @value 17 Killswitch - * @value 18 Armswitch - * @value 19 Transition - * @value 20 Gear - * + * @value 14 Orbit + * @value 15 Auto VTOL Takeoff + * @value 16 Killswitch + * @value 17 Arm + * @value 18 VTOL Transition + * @value 19 Gear + * @value 20 Photo + * @value 21 Video */ PARAM_DEFINE_INT32(RC_TRIG1_ACTION, 0); diff --git a/src/modules/rc_update/rc_update.cpp b/src/modules/rc_update/rc_update.cpp index 64f4754679..324e7bd6a1 100644 --- a/src/modules/rc_update/rc_update.cpp +++ b/src/modules/rc_update/rc_update.cpp @@ -64,7 +64,15 @@ static bool operator !=(const manual_control_switches_s &a, const manual_control RCUpdate::RCUpdate() : ModuleParams(nullptr), - WorkItem(MODULE_NAME, px4::wq_configurations::hp_default) + WorkItem(MODULE_NAME, px4::wq_configurations::hp_default), + _trigger_slots_hysteresis{ + systemlib::Hysteresis{false}, + systemlib::Hysteresis{false}, + systemlib::Hysteresis{false}, + systemlib::Hysteresis{false}, + systemlib::Hysteresis{false}, + systemlib::Hysteresis{false} + } { // initialize parameter handles for (unsigned i = 0; i < RC_MAX_CHAN_COUNT; i++) { @@ -96,13 +104,23 @@ RCUpdate::RCUpdate() : // shifted by 1 because param name starts at 1 char name[rc_parameter_map_s::PARAM_ID_LEN]; snprintf(name, rc_parameter_map_s::PARAM_ID_LEN, "RC_MAP_PARAM%d", i + 1); - _parameter_handles.rc_map_param[i] = param_find(name); + _trigger_channel_param_handles.rc_map_param[i] = param_find(name); + } + + // Find and set RC Channel & Actions for each Trigger actions (1 ~ 6) + char param_name_buf[17] = {}; + for (uint8_t trig_slot = 1; trig_slot <= RC_TRIG_SLOT_COUNT; trig_slot++) { + snprintf(param_name_buf, sizeof(param_name_buf), "RC_TRIG_%d_CHAN", trig_slot); + _trigger_channel_param_handles[trig_slot - 1] = param_find(param_name_buf); + snprintf(param_name_buf, sizeof(param_name_buf), "RC_TRIG_%d_ACTION", trig_slot); + _trigger_action_param_handles[trig_slot - 1] = param_find(param_name_buf); + } } rc_parameter_map_poll(true /* forced */); parameters_updated(); - _button_pressed_hysteresis.set_hysteresis_time_from(false, 50_ms); + //_button_pressed_hysteresis.set_hysteresis_time_from(false, 50_ms); } RCUpdate::~RCUpdate() @@ -602,9 +620,31 @@ void RCUpdate::UpdateManualSwitches(const hrt_abstime ×tamp_sample) } - for (uint8_t trig_slot = 0; trig_slot < RC_TRIG_SLOT_COUNT; trig_slot++) { + // Use the Generic RC Switch / Button only when the RC is in use + if (_manual_control_setpoint_sub.update() && + _manual_control_setpoint_sub.get().data_source == manual_control_setpoint_s::SOURCE_RC) { + _manual_control_setpoint_source_is_rc = true; + } - const bool is_btn = _param_rc_trig_btn_mask.get() && (1 << trig_slot); + // Go through the trigger slots and update the states + + for (uint8_t trig_slot = 1; trig_slot <= RC_TRIG_SLOT_COUNT; trig_slot++) { + + } + + // Update the Generic Action states + const uint8_t trig1_chan = _param_rc_trig1_chan.get(); + const uint8_t trig1_action = _param_rc_trig1_action.get(); + // Trigger Channel is configured + if (trig1_chan > 0) { + const bool is_btn = _param_rc_trig_btn_mask.get() & (1 << 0); + if (is_btn) { + + } + else { + // Is Switch + + } } else if (_param_rc_map_flightmode_buttons.get() > 0) { @@ -630,12 +670,6 @@ void RCUpdate::UpdateManualSwitches(const hrt_abstime ×tamp_sample) break; } } - - _button_pressed_hysteresis.set_state_and_update(is_consistent_button_press, hrt_absolute_time()); - - if (_button_pressed_hysteresis.get_state()) { - switches.mode_slot = _potential_button_press_slot; - } } switches.return_switch = get_rc_sw2pos_position(rc_channels_s::FUNCTION_RETURN, _param_rc_return_th.get()); diff --git a/src/modules/rc_update/rc_update.h b/src/modules/rc_update/rc_update.h index 03b729f552..03766134cd 100644 --- a/src/modules/rc_update/rc_update.h +++ b/src/modules/rc_update/rc_update.h @@ -48,6 +48,7 @@ #include #include #include + #include #include #include @@ -69,6 +70,34 @@ namespace rc_update // Number of Generic Trigger slots that can be configured static constexpr uint8_t RC_TRIG_SLOT_COUNT = 6; +// Enum class translation of the RC_TRIG#_ACTION values +static constexpr enum RC_TRIGGER_ACTIONS { + RC_TRIGGER_ACTION_UNASSIGNED = -1, + // Commander States (defined in commander_state.msg) + RC_TRIGGER_ACTION_MANUAL_FLIGHTMODE = 0, + RC_TRIGGER_ACTION_ALTITUDE_FLIGHTMODE = 1, + RC_TRIGGER_ACTION_POSITION_FLIGHTMODE = 2, + RC_TRIGGER_ACTION_MISSION_FLIHGTMODE = 3, + RC_TRIGGER_ACTION_HOLD_FLIGHTMODE = 4, + RC_TRIGGER_ACTION_RETURN_FLIGHTMODE = 5, + RC_TRIGGER_ACTION_ACRO_FLIGHTMODE = 6, + RC_TRIGGER_ACTION_OFFBOARD_FLIGHTMODE = 7, + RC_TRIGGER_ACTION_STABILIZED_FLIGHTMODE = 8, + RC_TRIGGER_ACTION_TAKEOFF = 10, + RC_TRIGGER_ACTION_LAND = 11, + RC_TRIGGER_ACTION_FOLLOW_ME_FLIGHTMODE = 12, + RC_TRIGGER_ACTION_PRECISION_LAND_FLIGHTMODE = 13, + RC_TRIGGER_ACTION_ORBIT_FLIGHTMODE = 14, + RC_TRIGGER_ACTION_AUTO_VTOL_TAKEOFF = 15, + // Non- Commander State Actions + RC_TRIGGER_ACTION_KILLSWITCH = 16, + RC_TRIGGER_ACTION_ARM = 17, + RC_TRIGGER_ACTION_VTOL_TRANSITION = 18, + RC_TRIGGER_ACTION_GEAR = 19, + RC_TRIGGER_ACTION_PHOTO = 20, + RC_TRIGGER_ACTION_VIDEO = 21 +}; + /** ** class RCUpdate * @@ -164,9 +193,8 @@ private: } _parameter_handles{}; uORB::SubscriptionCallbackWorkItem _input_rc_sub{this, ORB_ID(input_rc)}; - uORB::SubscriptionInterval _parameter_update_sub{ORB_ID(parameter_update), 1_s}; - + uORB::SubscriptionData _manual_control_setpoint_sub{ORB_ID(manual_control_setpoint)}; uORB::Subscription _rc_parameter_map_sub{ORB_ID(rc_parameter_map)}; uORB::Subscription _actuator_controls_3_sub{ORB_ID(actuator_controls_3)}; @@ -193,8 +221,12 @@ private: uint8_t _channel_count_previous{0}; uint8_t _input_source_previous{input_rc_s::RC_INPUT_SOURCE_UNKNOWN}; + // Flag to indicate that RC input is being used for manual control (whether we can use generic action) + bool _manual_control_setpoint_source_is_rc{false}; // Hysteresis objects to track status of the each trigger slots for generic action systemlib::Hysteresis _trigger_slots_hysteresis[RC_TRIG_SLOT_COUNT]; + param_t _trigger_channel_param_handles[RC_TRIG_SLOT_COUNT] {}; + param_t _trigger_action_param_handles[RC_TRIG_SLOT_COUNT] {}; systemlib::Hysteresis _rc_signal_lost_hysteresis{true}; @@ -212,8 +244,6 @@ private: (ParamInt) _param_rc_map_failsafe, (ParamInt) _param_rc_map_fltmode, (ParamInt) _param_rc_trig_btn_mask, - (ParamInt) _param_rc_trig1_chan, - (ParamInt) _param_rc_trig1_action, (ParamInt) _param_rc_map_flaps, (ParamInt) _param_rc_map_return_sw, (ParamInt) _param_rc_map_loiter_sw,