CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
Ardupilot

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place. Commercial Alternative to JupyterHub.

GitHub Repository: Ardupilot/ardupilot
Path: blob/master/Blimp/mode.cpp
Views: 1798
1
#include "Blimp.h"
2
3
/*
4
* High level calls to set and update flight modes logic for individual
5
* flight modes is in control_acro.cpp, control_stabilize.cpp, etc
6
*/
7
8
#include <AP_Vehicle/AP_MultiCopter.h>
9
10
/*
11
constructor for Mode object
12
*/
13
Mode::Mode(void) :
14
g(blimp.g),
15
g2(blimp.g2),
16
inertial_nav(blimp.inertial_nav),
17
ahrs(blimp.ahrs),
18
motors(blimp.motors),
19
loiter(blimp.loiter),
20
channel_right(blimp.channel_right),
21
channel_front(blimp.channel_front),
22
channel_up(blimp.channel_up),
23
channel_yaw(blimp.channel_yaw),
24
G_Dt(blimp.G_Dt)
25
{ };
26
27
// return the static controller object corresponding to supplied mode
28
Mode *Blimp::mode_from_mode_num(const Mode::Number mode)
29
{
30
Mode *ret = nullptr;
31
32
switch (mode) {
33
case Mode::Number::LAND:
34
ret = &mode_land;
35
break;
36
case Mode::Number::MANUAL:
37
ret = &mode_manual;
38
break;
39
case Mode::Number::VELOCITY:
40
ret = &mode_velocity;
41
break;
42
case Mode::Number::LOITER:
43
ret = &mode_loiter;
44
break;
45
case Mode::Number::RTL:
46
ret = &mode_rtl;
47
break;
48
default:
49
break;
50
}
51
52
return ret;
53
}
54
55
56
// set_mode - change flight mode and perform any necessary initialisation
57
// optional force parameter used to force the flight mode change (used only first time mode is set)
58
// returns true if mode was successfully set
59
// Some modes can always be set successfully but the return state of other flight modes should be checked and the caller should deal with failures appropriately
60
bool Blimp::set_mode(Mode::Number mode, ModeReason reason)
61
{
62
63
// return immediately if we are already in the desired mode
64
if (mode == control_mode) {
65
control_mode_reason = reason;
66
return true;
67
}
68
69
Mode *new_flightmode = mode_from_mode_num((Mode::Number)mode);
70
if (new_flightmode == nullptr) {
71
notify_no_such_mode((uint8_t)mode);
72
return false;
73
}
74
75
bool ignore_checks = !motors->armed(); // allow switching to any mode if disarmed. We rely on the arming check to perform
76
77
if (!ignore_checks &&
78
new_flightmode->requires_GPS() &&
79
!blimp.position_ok()) {
80
gcs().send_text(MAV_SEVERITY_WARNING, "Mode change failed: %s requires position", new_flightmode->name());
81
LOGGER_WRITE_ERROR(LogErrorSubsystem::FLIGHT_MODE, LogErrorCode(mode));
82
return false;
83
}
84
85
// check for valid altitude if old mode did not require it but new one does
86
// we only want to stop changing modes if it could make things worse
87
if (!ignore_checks &&
88
!blimp.ekf_alt_ok() &&
89
flightmode->has_manual_throttle() &&
90
!new_flightmode->has_manual_throttle()) {
91
gcs().send_text(MAV_SEVERITY_WARNING, "Mode change failed: %s need alt estimate", new_flightmode->name());
92
LOGGER_WRITE_ERROR(LogErrorSubsystem::FLIGHT_MODE, LogErrorCode(mode));
93
return false;
94
}
95
96
if (!new_flightmode->init(ignore_checks)) {
97
gcs().send_text(MAV_SEVERITY_WARNING,"Flight mode change failed %s", new_flightmode->name());
98
LOGGER_WRITE_ERROR(LogErrorSubsystem::FLIGHT_MODE, LogErrorCode(mode));
99
return false;
100
}
101
102
// perform any cleanup required by previous flight mode
103
exit_mode(flightmode, new_flightmode);
104
105
// update flight mode
106
flightmode = new_flightmode;
107
control_mode = mode;
108
control_mode_reason = reason;
109
#if HAL_LOGGING_ENABLED
110
logger.Write_Mode((uint8_t)control_mode, reason);
111
#endif
112
gcs().send_message(MSG_HEARTBEAT);
113
114
// update notify object
115
notify_flight_mode();
116
117
// return success
118
return true;
119
}
120
121
bool Blimp::set_mode(const uint8_t new_mode, const ModeReason reason)
122
{
123
static_assert(sizeof(Mode::Number) == sizeof(new_mode), "The new mode can't be mapped to the vehicles mode number");
124
#ifdef DISALLOW_GCS_MODE_CHANGE_DURING_RC_FAILSAFE
125
if (reason == ModeReason::GCS_COMMAND && blimp.failsafe.radio) {
126
// don't allow mode changes while in radio failsafe
127
return false;
128
}
129
#endif
130
return blimp.set_mode(static_cast<Mode::Number>(new_mode), reason);
131
}
132
133
// update_flight_mode - calls the appropriate attitude controllers based on flight mode
134
// called at 100hz or more
135
void Blimp::update_flight_mode()
136
{
137
flightmode->run();
138
}
139
140
// exit_mode - high level call to organise cleanup as a flight mode is exited
141
void Blimp::exit_mode(Mode *&old_flightmode,
142
Mode *&new_flightmode) {}
143
144
// notify_flight_mode - sets notify object based on current flight mode. Only used for OreoLED notify device
145
void Blimp::notify_flight_mode()
146
{
147
AP_Notify::flags.autopilot_mode = flightmode->is_autopilot();
148
AP_Notify::flags.flight_mode = (uint8_t)control_mode;
149
notify.set_flight_mode_str(flightmode->name4());
150
}
151
152
void Mode::update_navigation()
153
{
154
// run autopilot to make high level decisions about control modes
155
run_autopilot();
156
}
157
158
// returns desired thrust/acceleration
159
void Mode::get_pilot_input(Vector3f &pilot, float &yaw)
160
{
161
// throttle failsafe check
162
if (blimp.failsafe.radio || !rc().has_ever_seen_rc_input()) {
163
pilot.y = 0;
164
pilot.x = 0;
165
pilot.z = 0;
166
yaw = 0;
167
return;
168
}
169
// fetch pilot inputs
170
pilot.y = channel_right->get_control_in() / float(RC_SCALE);
171
pilot.x = channel_front->get_control_in() / float(RC_SCALE);
172
//TODO: need to make this channel_up instead, and then have it .negative. before being sent to pilot.z -> this is "throttle" channel, so higher = up.
173
pilot.z = -channel_up->get_control_in() / float(RC_SCALE);
174
yaw = channel_yaw->get_control_in() / float(RC_SCALE);
175
}
176
177
bool Mode::is_disarmed_or_landed() const
178
{
179
if (!motors->armed() || !blimp.ap.auto_armed || blimp.ap.land_complete) {
180
return true;
181
}
182
return false;
183
}
184
185
bool Mode::set_mode(Mode::Number mode, ModeReason reason)
186
{
187
return blimp.set_mode(mode, reason);
188
}
189
190
GCS_Blimp &Mode::gcs()
191
{
192
return blimp.gcs();
193
}
194
195