3838
3939namespace rosflight_firmware
4040{
41- typedef enum
42- {
43- ATT_MODE_RATE,
44- ATT_MODE_ANGLE
45- } att_mode_t ;
46-
47- typedef struct
48- {
49- RC::Stick rc_channel;
50- uint32_t last_override_time;
51- } rc_stick_override_t ;
52-
53- rc_stick_override_t rc_stick_override[] = {{RC::STICK_X, 0 }, {RC::STICK_Y, 0 }, {RC::STICK_Z, 0 }};
54-
55- typedef struct
56- {
57- control_channel_t * rc;
58- control_channel_t * onboard;
59- control_channel_t * combined;
60- } mux_t ;
6141
6242CommandManager::CommandManager (ROSflight & _rf)
6343 : RF_(_rf)
6444 , failsafe_command_(multirotor_failsafe_command_)
6545{}
6646
67- void CommandManager::init () { init_failsafe (); }
47+ void CommandManager::init ()
48+ {
49+ init_failsafe ();
50+ rc_override_ = determine_override_status ();
51+ }
6852
6953void CommandManager::param_change_callback (uint16_t param_id)
7054{
@@ -124,27 +108,22 @@ void CommandManager::interpret_rc(void)
124108 rc_command_.Qz .value = RF_.rc_ .stick (RC::STICK_Z);
125109
126110 // Load the RC command based on the axis associated with the RC F command
111+ rc_command_.Fx .value = 0.0 ;
112+ rc_command_.Fy .value = 0.0 ;
113+ rc_command_.Fz .value = 0.0 ;
127114 switch (static_cast <rc_f_axis_t >(RF_.params_ .get_param_int (PARAM_RC_F_AXIS))) {
128- case X_AXIS: // RC F = X axis
115+ case X_AXIS:
129116 rc_command_.Fx .value = RF_.rc_ .stick (RC::STICK_F);
130- rc_command_.Fy .value = 0.0 ;
131- rc_command_.Fz .value = 0.0 ;
132117 break ;
133- case Y_AXIS: // RC F = Y axis
134- rc_command_.Fx .value = 0.0 ;
118+ case Y_AXIS:
135119 rc_command_.Fy .value = RF_.rc_ .stick (RC::STICK_F);
136- rc_command_.Fz .value = 0.0 ;
137120 break ;
138121 case Z_AXIS:
139- rc_command_.Fx .value = 0.0 ;
140- rc_command_.Fy .value = 0.0 ;
141122 rc_command_.Fz .value = RF_.rc_ .stick (RC::STICK_F);
142123 break ;
143124 default :
144125 RF_.comm_manager_ .log (CommLinkInterface::LogSeverity::LOG_WARNING,
145126 " Invalid RC F axis. Defaulting to z-axis." );
146- rc_command_.Fx .value = 0.0 ;
147- rc_command_.Fy .value = 0.0 ;
148127 rc_command_.Fz .value = RF_.rc_ .stick (RC::STICK_F);
149128 break ;
150129 }
@@ -199,50 +178,60 @@ bool CommandManager::stick_deviated(MuxChannel channel)
199178 uint32_t now = RF_.board_ .clock_millis ();
200179
201180 // if we are still in the lag time, return true
202- if (now < rc_stick_override_ [channel].last_override_time
181+ if (now < channel_override_ [channel].last_override_time
203182 + RF_.params_ .get_param_int (PARAM_OVERRIDE_LAG_TIME)) {
204183 return true ;
205184 } else {
206- if (fabsf (RF_.rc_ .stick (rc_stick_override_ [channel].rc_channel ))
185+ if (fabsf (RF_.rc_ .stick (channel_override_ [channel].rc_channel ))
207186 > RF_.params_ .get_param_float (PARAM_RC_OVERRIDE_DEVIATION)) {
208- rc_stick_override_ [channel].last_override_time = now;
187+ channel_override_ [channel].last_override_time = now;
209188 return true ;
210189 }
211190 return false ;
212191 }
213192}
214193
215- uint8_t CommandManager::do_roll_pitch_yaw_muxing (MuxChannel channel )
194+ uint16_t CommandManager::determine_override_status ( )
216195{
217- bool override_this_channel = false ;
218196 // Check if the override switch exists and is triggered, or if the sticks have deviated enough to
219197 // trigger an override
220- if ((RF_.rc_ .switch_mapped (RC::SWITCH_ATT_OVERRIDE) && RF_.rc_ .switch_on (RC::SWITCH_ATT_OVERRIDE))
221- || stick_deviated (channel)) {
222- override_this_channel = true ;
223- } else { // Otherwise only have RC override if the offboard channel is inactive
224- if (muxes[channel].onboard ->active ) {
225- override_this_channel = false ;
226- } else {
227- override_this_channel = true ;
228- }
198+ uint16_t rc_override{0 };
199+ if (RF_.rc_ .switch_mapped (RC::SWITCH_ATT_OVERRIDE) && RF_.rc_ .switch_on (RC::SWITCH_ATT_OVERRIDE)) {
200+ rc_override |= OVERRIDE_ATT_SWITCH;
229201 }
230- // set the combined channel output depending on whether RC is overriding for this channel or not
231- *muxes[channel].combined = override_this_channel ? *muxes[channel].rc : *muxes[channel].onboard ;
232- if (override_this_channel) return 1U ;
233- else return 0 ;
202+ if (RF_.rc_ .switch_mapped (RC::SWITCH_THROTTLE_OVERRIDE) && RF_.rc_ .switch_on (RC::SWITCH_THROTTLE_OVERRIDE)) {
203+ rc_override |= OVERRIDE_THR_SWITCH;
204+ }
205+
206+ rc_override |= check_if_attitude_channel_is_overriden_by_rc (MUX_QX);
207+ rc_override |= check_if_attitude_channel_is_overriden_by_rc (MUX_QY);
208+ rc_override |= check_if_attitude_channel_is_overriden_by_rc (MUX_QZ);
209+ rc_override |= check_if_throttle_channel_is_overriden_by_rc ();
210+
211+ return rc_override;
234212}
235213
236- uint8_t CommandManager::do_throttle_muxing (void )
214+ uint16_t CommandManager::check_if_attitude_channel_is_overriden_by_rc (MuxChannel channel)
215+ {
216+ uint16_t rc_overrides{0 };
217+ if (stick_deviated (channel)) {
218+ rc_overrides |= channel_override_[channel].stick_override_reason ;
219+ }
220+ if (!(muxes_[channel].onboard ->active )) {
221+ rc_overrides |= channel_override_[channel].offboard_inactive_override_reason ;
222+ }
223+ return rc_overrides;
224+ }
225+
226+ uint16_t CommandManager::check_if_throttle_channel_is_overriden_by_rc ()
237227{
238- bool override_this_channel = false ;
239228 MuxChannel selected_channel;
240- // Determine which channel to check based on which axis the RC channel corresponds to
229+ // Determine which channel to check based on which axis the RC F channel corresponds to
241230 switch (static_cast <rc_f_axis_t >(RF_.params_ .get_param_int (PARAM_RC_F_AXIS))) {
242- case X_AXIS:
231+ case X_AXIS:
243232 selected_channel = MUX_FX;
244233 break ;
245- case Y_AXIS:
234+ case Y_AXIS:
246235 selected_channel = MUX_FY;
247236 break ;
248237 case Z_AXIS:
@@ -255,43 +244,38 @@ uint8_t CommandManager::do_throttle_muxing(void)
255244 break ;
256245 }
257246
258- // Check if the override switch exists and is triggered
259- if (RF_.rc_ .switch_mapped (RC::SWITCH_THROTTLE_OVERRIDE)
260- && RF_.rc_ .switch_on (RC::SWITCH_THROTTLE_OVERRIDE)) {
261- override_this_channel = true ;
262- } else { // Otherwise check if the offboard throttle channel is active, if it isn't, have RC override
263- if (muxes[selected_channel].onboard ->active ) {
264- // Check if the parameter flag is set to have us always take the smaller throttle
265- if (RF_.params_ .get_param_int (PARAM_RC_OVERRIDE_TAKE_MIN_THROTTLE)) {
266- override_this_channel = (muxes[selected_channel].rc ->value < muxes[selected_channel].onboard ->value );
267- } else {
268- override_this_channel = false ;
269- }
270- } else {
271- override_this_channel = true ;
247+ uint16_t rc_overrides{0 };
248+ if (!(muxes_[selected_channel].onboard ->active )) {
249+ rc_overrides |= OVERRIDE_OFFBOARD_T_INACTIVE;
250+ }
251+ if (RF_.params_ .get_param_int (PARAM_RC_OVERRIDE_TAKE_MIN_THROTTLE)) {
252+ if (muxes_[selected_channel].rc ->value < muxes_[selected_channel].onboard ->value ) {
253+ rc_overrides |= OVERRIDE_T;
272254 }
273255 }
256+ return rc_overrides;
257+ }
274258
275- // Set the combined channel output depending on whether RC is overriding for this channel or not
276- // Either RC overrides all force inputs, or none
277- if (override_this_channel) {
278- *muxes[MUX_FX].combined = *muxes[MUX_FX].rc ;
279- *muxes[MUX_FY].combined = *muxes[MUX_FY].rc ;
280- *muxes[MUX_FZ].combined = *muxes[MUX_FZ].rc ;
281- } else {
282- *muxes[MUX_FX].combined = *muxes[MUX_FX].onboard ;
283- *muxes[MUX_FY].combined = *muxes[MUX_FY].onboard ;
284- *muxes[MUX_FZ].combined = *muxes[MUX_FZ].onboard ;
259+ void CommandManager::do_muxing (uint16_t rc_override)
260+ {
261+ for (uint8_t channel{0 }; channel < NUM_MUX_CHANNELS; ++channel) {
262+ do_channel_muxing (static_cast <MuxChannel>(channel), rc_override);
285263 }
286- return override_this_channel;
287264}
288265
289- uint8_t CommandManager::rc_override_active () { return rc_override_; }
266+ void CommandManager::do_channel_muxing (MuxChannel channel, uint16_t rc_override )
267+ {
268+ bool override_this_channel = (rc_override & channel_override_[channel].override_mask );
269+ // set the combined channel output depending on whether RC is overriding for this channel or not
270+ *muxes_[channel].combined = override_this_channel ? *muxes_[channel].rc : *muxes_[channel].onboard ;
271+ }
272+
273+ uint16_t CommandManager::get_rc_override () { return rc_override_; }
290274
291275bool CommandManager::offboard_control_active ()
292276{
293- for (int i = 0 ; i < 4 ; i++ ) {
294- if (muxes[i ].onboard ->active ) { return true ; }
277+ for (uint8_t channel{ 0 }; channel < NUM_MUX_CHANNELS; ++channel ) {
278+ if (muxes_[channel ].onboard ->active ) { return true ; }
295279 }
296280 return false ;
297281}
@@ -316,7 +300,7 @@ void CommandManager::override_combined_command_with_rc()
316300
317301bool CommandManager::run ()
318302{
319- bool last_rc_override = rc_override_active ();
303+ uint16_t last_rc_override = get_rc_override ();
320304
321305 // Check for and apply failsafe command
322306 if (RF_.state_manager_ .state ().failsafe ) {
@@ -338,21 +322,19 @@ bool CommandManager::run()
338322 }
339323
340324 // Perform muxing
341- rc_override_ = do_roll_pitch_yaw_muxing (MUX_QX);
342- rc_override_ |= do_roll_pitch_yaw_muxing (MUX_QY);
343- rc_override_ |= do_roll_pitch_yaw_muxing (MUX_QZ);
344- rc_override_ += 2U *do_throttle_muxing ();
325+ rc_override_ = determine_override_status ();
326+ do_muxing (rc_override_);
345327
346328 // Light to indicate override
347- if (rc_override_active () ) {
329+ if (rc_override_ ) {
348330 RF_.board_ .led0_on ();
349331 } else {
350332 RF_.board_ .led0_off ();
351333 }
352334 }
353335
354336 // There was a change in rc_override state
355- if (last_rc_override != rc_override_active ()) { RF_.comm_manager_ .update_status (); }
337+ if (last_rc_override != get_rc_override ()) { RF_.comm_manager_ .update_status (); }
356338 return true ;
357339}
358340
0 commit comments