New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Plane: basic automatic emergency parachute release at critical altitude error in AUTO. #3703
Changes from 1 commit
ba50d78
6c83c0a
05c0712
e7d4fb7
8587bc7
e6017b1
ab276e5
e7048e7
e22082a
ca23e3f
a1132f3
3187145
aac4198
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1058,10 +1058,26 @@ const AP_Param::Info Plane::var_info[] = { | |
GOBJECT(relay, "RELAY_", AP_Relay), | ||
|
||
#if PARACHUTE == ENABLED | ||
// @Group: CHUTE_ | ||
// @Group: CHUTE_ | ||
// @Path: ../libraries/AP_Parachute/AP_Parachute.cpp | ||
GOBJECT(parachute, "CHUTE_", AP_Parachute), | ||
|
||
// @Param: CHUTE_AUTO_ON | ||
// @DisplayName: Parachute automatic emergency release | ||
// @Description: Parachute automatic emergency release enabled or disabled. | ||
// @Values: 0:Disabled,1:Enabled | ||
// @User: Standard | ||
GSCALAR(parachute_auto_enabled, "CHUTE_AUTO_ON", 0), | ||
|
||
// @Param: CHUTE_AUTO_ERROR | ||
// @DisplayName: Altitude deviation for parachute release | ||
// @Description: Altitude deviation at which to release parachute if in AUTO and CHUTE_AUTO_ON. | ||
// @Units: Meters | ||
// @Range: 10 32767 | ||
// @Increment: 1 | ||
// @User: Standard | ||
GSCALAR(parachute_auto_error, "CHUTE_AUTO_ERROR", 20), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. When you move these to AP_Parachute, you can surround them with # if APM_BUILD_TYPE(APM_BUILD_ArduPlane) so they only compile for plane. Same goes for the timer variable and accessor function. |
||
|
||
// @Param: CHUTE_CHAN | ||
// @DisplayName: Parachute release channel | ||
// @Description: If set to a non-zero value then this is an RC input channel number to use for manually releasing the parachute. When this channel goes above 1700 the parachute will be released | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -146,6 +146,8 @@ class Parameters { | |
k_param_parachute, | ||
k_param_arming = 100, | ||
k_param_parachute_channel, | ||
k_param_parachute_auto_enabled, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. the order here is extremely important. You can't push down other k_params indexes. You must use an unused index There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. OK, I see now. Where should I move these? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. into AP_Parachute There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. the k_params are not needed if you are within a lib |
||
k_param_parachute_auto_error, | ||
k_param_crash_accel_threshold, | ||
k_param_override_safety, | ||
|
||
|
@@ -510,6 +512,8 @@ class Parameters { | |
#endif | ||
AP_Int16 gcs_pid_mask; | ||
AP_Int8 parachute_channel; | ||
AP_Int8 parachute_auto_enabled; | ||
AP_Int16 parachute_auto_error; | ||
|
||
// RC channels | ||
RC_Channel rc_1; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,12 +3,15 @@ | |
#include "Plane.h" | ||
|
||
|
||
/* | ||
/* | ||
call parachute library update | ||
*/ | ||
void Plane::parachute_check() | ||
{ | ||
parachute.update(); | ||
|
||
// check if there is an emergency situation | ||
parachute_emergency_check(); | ||
} | ||
|
||
/* | ||
|
@@ -19,7 +22,7 @@ void Plane::parachute_release() | |
if (parachute.released()) { | ||
return; | ||
} | ||
|
||
// send message to gcs and dataflash | ||
gcs_send_text(MAV_SEVERITY_CRITICAL,"Parachute: Released"); | ||
|
||
|
@@ -56,3 +59,62 @@ bool Plane::parachute_manual_release() | |
|
||
return true; | ||
} | ||
|
||
// Code to detect loss of control for ArduPlane | ||
#define PARACHUTE_CHECK_TRIGGER_SEC 1 // 1 second of loss of control triggers the parachute | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. don't declare defines right in the middle of other code. Put it at the top. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You're right. I was just replicating what was in ArduCopter/crash_check.cpp (although it probably has a define in the middle of the code because of the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This message was created automatically by mail delivery software. A message that you sent could not be delivered to one or more of its dupuyyann@gmail.com ------- This is a copy of the message, including all the headers. ------ Content preview: > @@ -56,3 +59,55 @@ bool Plane::parachute_manual_release() Content analysis details: (-1.4 points, 5.0 required) pts rule name description -2.3 RCVD_IN_DNSWL_MED RBL: Sender listed at http://www.dnswl.org/, medium ----==_mimepart_56e7e9549f2f3_5c9a3fba4a0e12a01564035
You're right. I was just replicating what was in ArduCopter/crash_check.cpp (although it probably has a define in the middle of the code because of the You are receiving this because you are subscribed to this thread. > @@ -56,3 +59,55 @@ bool Plane::parachute_manual_release() > > return true; > } > + > +// Code to detect loss of control for ArduPlane > +#define PARACHUTE_CHECK_TRIGGER_SEC 1 // 1 second of loss of control triggers the parachute You're right. I was just replicating what was in ArduCopter/crash_check.cpp (although it probably has a define in the middle of the code because of the — ----==_mimepart_56e7e9549f2f3_5c9a3fba4a0e12a01564035-- |
||
|
||
/* | ||
parachute_emergency_check - trigger the release of the parachute | ||
automatically if a critical situation is detected | ||
*/ | ||
void Plane::parachute_emergency_check() | ||
{ | ||
static uint32_t control_loss_ms; // time when we first lost control and never regained it | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. no statics allowed because it still creates only 1 if you have two classes of Plane (weird, I know, but maybe something will in the future). Please declare it in the class and rename it so it's global friendly. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do you mean it will be possible to create two instances of Plane class in the future? Why and how would that work – maybe there's some discussion about this somewhere I could read about it, if it has already been explained? I thought it should be some sort of singleton. Is it going to diverge from Copter architecture? Static variables are all over the place in Plane, e.g.: And there are probably even more in Copter code. Is there a plan to refactor them? I'm interested, because I was just following the existing architecture and not having a singleton Plane just sounds unintuitive (although, of course, might be wrong). There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There is no "plan" but the concern is a relatively new one. Since ArduPilot is moving more and more towards Linux based systems you never know how the class ends up getting used! Not using static variables removes some chances of bugs. If things were to change it's easier to enforce it during development instead of all at once at the end. The other uses of static have been there a long time and should be changed too. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why would Linux not allow using a singleton? Can you maybe point me to some existing Plane code where statics were replaced by globals? Is this move from static variables to globals documented anywhere in Ardupilot repository (GitHub issue, mailing list, etc)? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is there any example in existing code where this was already done, so I could replicate that? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Just make a variable in Plane.h and remove the static from here. Take a look at throttle_watt_limit_timer_ms |
||
uint32_t now = millis(); | ||
|
||
// exit immediately if parachute or automatic release is not enabled, or already released | ||
if (!parachute.enabled() || parachute.released() || g.parachute_auto_enabled == 0) { | ||
control_loss_ms = 0; | ||
return; | ||
} | ||
|
||
// only automatically release in AUTO mode | ||
if (control_mode != AUTO) { | ||
control_loss_ms = 0; | ||
return; | ||
} | ||
|
||
// do not release if vehicle is not flying | ||
if (!is_flying()) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. is_flying may go false during a stall because both GPS ground speed and airspeed drop to low numbers. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. OK. I think it should be safe to remove this check, because we also have the Also, since There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. you're probably right. The normal use-case for a manual release is a planned one while flying, but if you manually do it on the way down it sure would be nice for it to work! |
||
control_loss_ms = 0; | ||
return; | ||
} | ||
|
||
// do not release if taking off or landing | ||
if (auto_state.takeoff_complete == false || mission.get_current_nav_cmd().id == MAV_CMD_NAV_LAND) { | ||
control_loss_ms = 0; | ||
return; | ||
} | ||
|
||
if (relative_altitude() < parachute.alt_min()) { | ||
control_loss_ms = 0; | ||
return; | ||
} | ||
|
||
// do not release if we are flying within given error | ||
if (altitude_error_cm < g.parachute_auto_error * 100.0f) { | ||
control_loss_ms = 0; | ||
return; | ||
} | ||
|
||
// at this point we consider control lost | ||
if (control_loss_ms == 0) { | ||
gcs_send_text_fmt(MAV_SEVERITY_WARNING, "Crash: Starting to lose control, %d m error", altitude_error_cm / 100); | ||
control_loss_ms = now; | ||
} else if (now - control_loss_ms > PARACHUTE_CHECK_TRIGGER_SEC * 1000) { | ||
// we have lost control for too long | ||
gcs_send_text_fmt(MAV_SEVERITY_WARNING, "Crash: Critical altitude error %d m", altitude_error_cm / 100); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. use *0.01f instead of /100, it's computationally much easier. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sure, I'll change it. However, these messages are sent very very rarely and this division operation should be negligible compared to all the function calls, string formatting, and sending it to the GCS. I just thought division was more readable for me. |
||
parachute_release(); | ||
control_loss_ms = 0; | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Move these to line 54 of this
https://github.com/diydrones/ardupilot/blob/master/libraries/AP_Parachute/AP_Parachute.cpp