forked from ArduPilot/ardupilot
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathRC_Channel.cpp
255 lines (219 loc) · 7.09 KB
/
RC_Channel.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
#include "Rover.h"
#include "RC_Channel.h"
// defining these two macros and including the RC_Channels_VarInfo
// header defines the parameter information common to all vehicle
// types
#define RC_CHANNELS_SUBCLASS RC_Channels_Rover
#define RC_CHANNEL_SUBCLASS RC_Channel_Rover
#include <RC_Channel/RC_Channels_VarInfo.h>
int8_t RC_Channels_Rover::flight_mode_channel_number() const
{
return rover.g.mode_channel;
}
void RC_Channel_Rover::mode_switch_changed(modeswitch_pos_t new_pos)
{
if (new_pos < 0 || (uint8_t)new_pos > rover.num_modes) {
// should not have been called
return;
}
Mode *new_mode = rover.mode_from_mode_num((Mode::Number)rover.modes[new_pos].get());
if (new_mode != nullptr) {
rover.set_mode(*new_mode, ModeReason::RC_COMMAND);
}
}
// init_aux_switch_function - initialize aux functions
void RC_Channel_Rover::init_aux_function(const aux_func_t ch_option, const AuxSwitchPos ch_flag)
{
// init channel options
switch (ch_option) {
// the following functions do not need initialising:
case AUX_FUNC::ACRO:
case AUX_FUNC::AUTO:
case AUX_FUNC::FOLLOW:
case AUX_FUNC::GUIDED:
case AUX_FUNC::HOLD:
case AUX_FUNC::LEARN_CRUISE:
case AUX_FUNC::LOITER:
case AUX_FUNC::MAINSAIL:
case AUX_FUNC::MANUAL:
case AUX_FUNC::PITCH:
case AUX_FUNC::ROLL:
case AUX_FUNC::WALKING_HEIGHT:
case AUX_FUNC::RTL:
case AUX_FUNC::SAILBOAT_TACK:
case AUX_FUNC::SAVE_TRIM:
case AUX_FUNC::SAVE_WP:
case AUX_FUNC::SIMPLE:
case AUX_FUNC::SMART_RTL:
case AUX_FUNC::STEERING:
break;
case AUX_FUNC::SAILBOAT_MOTOR_3POS:
do_aux_function_sailboat_motor_3pos(ch_flag);
break;
default:
RC_Channel::init_aux_function(ch_option, ch_flag);
break;
}
}
bool RC_Channels_Rover::has_valid_input() const
{
if (rover.failsafe.bits & FAILSAFE_EVENT_THROTTLE) {
return false;
}
return true;
}
RC_Channel * RC_Channels_Rover::get_arming_channel(void) const
{
return rover.channel_steer;
}
void RC_Channel_Rover::do_aux_function_change_mode(Mode &mode,
const AuxSwitchPos ch_flag)
{
switch (ch_flag) {
case AuxSwitchPos::HIGH:
rover.set_mode(mode, ModeReason::RC_COMMAND);
break;
case AuxSwitchPos::MIDDLE:
// do nothing
break;
case AuxSwitchPos::LOW:
if (rover.control_mode == &mode) {
rc().reset_mode_switch();
}
}
}
void RC_Channel_Rover::add_waypoint_for_current_loc()
{
// create new mission command
AP_Mission::Mission_Command cmd = {};
// set new waypoint to current location
cmd.content.location = rover.current_loc;
// make the new command to a waypoint
cmd.id = MAV_CMD_NAV_WAYPOINT;
// save command
if (rover.mode_auto.mission.add_cmd(cmd)) {
hal.console->printf("Added waypoint %u", (unsigned)rover.mode_auto.mission.num_commands());
}
}
void RC_Channel_Rover::do_aux_function_sailboat_motor_3pos(const AuxSwitchPos ch_flag)
{
switch (ch_flag) {
case AuxSwitchPos::HIGH:
rover.g2.sailboat.set_motor_state(Sailboat::UseMotor::USE_MOTOR_ALWAYS);
break;
case AuxSwitchPos::MIDDLE:
rover.g2.sailboat.set_motor_state(Sailboat::UseMotor::USE_MOTOR_ASSIST);
break;
case AuxSwitchPos::LOW:
rover.g2.sailboat.set_motor_state(Sailboat::UseMotor::USE_MOTOR_NEVER);
break;
}
}
void RC_Channel_Rover::do_aux_function(const aux_func_t ch_option, const AuxSwitchPos ch_flag)
{
switch (ch_option) {
case AUX_FUNC::DO_NOTHING:
break;
case AUX_FUNC::SAVE_WP:
if (ch_flag == AuxSwitchPos::HIGH) {
// do nothing if in AUTO mode
if (rover.control_mode == &rover.mode_auto) {
return;
}
// if disarmed clear mission and set home to current location
if (!rover.arming.is_armed()) {
rover.mode_auto.mission.clear();
if (!rover.set_home_to_current_location(false)) {
// ignored
}
return;
}
// record the waypoint if not in auto mode
if (rover.control_mode != &rover.mode_auto) {
if (rover.mode_auto.mission.num_commands() == 0) {
// add a home location....
add_waypoint_for_current_loc();
}
add_waypoint_for_current_loc();
}
}
break;
// learn cruise speed and throttle
case AUX_FUNC::LEARN_CRUISE:
if (ch_flag == AuxSwitchPos::HIGH) {
rover.cruise_learn_start();
}
break;
// set mode to Manual
case AUX_FUNC::MANUAL:
do_aux_function_change_mode(rover.mode_manual, ch_flag);
break;
// set mode to Acro
case AUX_FUNC::ACRO:
do_aux_function_change_mode(rover.mode_acro, ch_flag);
break;
// set mode to Steering
case AUX_FUNC::STEERING:
do_aux_function_change_mode(rover.mode_steering, ch_flag);
break;
// set mode to Hold
case AUX_FUNC::HOLD:
do_aux_function_change_mode(rover.mode_hold, ch_flag);
break;
// set mode to Auto
case AUX_FUNC::AUTO:
do_aux_function_change_mode(rover.mode_auto, ch_flag);
break;
// set mode to RTL
case AUX_FUNC::RTL:
do_aux_function_change_mode(rover.mode_rtl, ch_flag);
break;
// set mode to SmartRTL
case AUX_FUNC::SMART_RTL:
do_aux_function_change_mode(rover.mode_smartrtl, ch_flag);
break;
// set mode to Guided
case AUX_FUNC::GUIDED:
do_aux_function_change_mode(rover.mode_guided, ch_flag);
break;
// Set mode to LOITER
case AUX_FUNC::LOITER:
do_aux_function_change_mode(rover.mode_loiter, ch_flag);
break;
// Set mode to Follow
case AUX_FUNC::FOLLOW:
do_aux_function_change_mode(rover.mode_follow, ch_flag);
break;
// set mode to Simple
case AUX_FUNC::SIMPLE:
do_aux_function_change_mode(rover.mode_simple, ch_flag);
break;
// trigger sailboat tack
case AUX_FUNC::SAILBOAT_TACK:
// any switch movement interpreted as request to tack
rover.control_mode->handle_tack_request();
break;
// sailboat motor state 3pos
case AUX_FUNC::SAILBOAT_MOTOR_3POS:
do_aux_function_sailboat_motor_3pos(ch_flag);
break;
// save steering trim
case AUX_FUNC::SAVE_TRIM:
if (!rover.g2.motors.have_skid_steering() && rover.arming.is_armed() &&
(rover.control_mode != &rover.mode_loiter)
&& (rover.control_mode != &rover.mode_hold) && ch_flag == AuxSwitchPos::HIGH) {
SRV_Channels::set_trim_to_servo_out_for(SRV_Channel::k_steering);
gcs().send_text(MAV_SEVERITY_CRITICAL, "Steering trim saved!");
}
break;
// manual input, nothing to do
case AUX_FUNC::MAINSAIL:
case AUX_FUNC::PITCH:
case AUX_FUNC::ROLL:
case AUX_FUNC::WALKING_HEIGHT:
break;
default:
RC_Channel::do_aux_function(ch_option, ch_flag);
break;
}
}