Skip to content
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

UAVCAN pre-arm checks on escs_status (cleanup of #12153) #12641

Merged
merged 10 commits into from
Aug 9, 2019

Conversation

cmic0
Copy link
Contributor

@cmic0 cmic0 commented Aug 6, 2019

This is a cleaned-up version of #12153.
Addressed @RomanBapst review comments:

Test log:
https://logs.px4.io/plot_app?log=5b7f4b1c-9c1a-4f52-bdb8-25d6bb5e13e1

@@ -1010,6 +1010,12 @@ bool prearm_check(orb_advert_t *mavlink_log_pub, const vehicle_status_flags_s &s

}

if (status_flags.condition_escs_error && !status_flags.circuit_breaker_engaged_escs_check) {
mavlink_log_critical(mavlink_log_pub, "Arming denied! One or more ESCs are offline");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if (prearm_ok && reportFailures) {

if (rotor_count > 0) {
break;

} else { mixer = mixer -> _next;}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Replace with:

		}
                mixer = mixer->_next;

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Uh, In the original PR was like that but in the review I was suggested to use break for exiting the while loop.
What is the best practice for exiting the while loop?
The reference says that breaks can be used for exiting while loops, so i guess is just a madder of best choice?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not about the break, you can leave it in. But if you break you don't need the else, and removing it makes the code more readable.
As for best practices, it depends: exiting a larger loop from within many nested cases is prone to errors and harder to understand. Adding a break in a simple loop on the other hand can make the code simpler.

@@ -1123,6 +1123,11 @@ UavcanNode::ioctl(file *filp, int cmd, unsigned long arg)
} else {

_mixers->groups_required(_groups_required);
PX4_INFO("Groups required %d", _groups_required);

_rotor_count = _mixers->get_multirotor_count();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Keep this locally:

Suggested change
_rotor_count = _mixers->get_multirotor_count();
int rotor_count = _mixers->get_multirotor_count();

@@ -14,14 +14,15 @@ bool condition_local_velocity_valid # set to true by the commander app if the q
bool condition_local_altitude_valid
bool condition_power_input_valid # set if input power is valid
bool condition_battery_healthy # set if battery is available and not low

bool condition_escs_error # set to true in case of standard ESCs that do not provide status OR if all the ESCs are online
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment looks incorrect.


rotor_count = mixer->get_multirotor_count();

if (rotor_count > 0) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are you not summing all up? Would IMO be more robust.


uint8_t UavcanEscController::check_escs_status()
{
int esc_status_flags = 255;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you only set the bits for the ones that are really online?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually yes, I think in an early implementation I used this logic to fix something but after reviewing makes completely sense to re-invert the logic :)!

* Circuit breaker for ESCs status check
*
* Setting this parameter to 271828 will disable offline ESCs detection.
* If this check is enabled, then the ESCs check will fail is not all the ESCs are reporting their status.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* If this check is enabled, then the ESCs check will fail is not all the ESCs are reporting their status.
* If this check is enabled, then the ESCs check will fail if not all the ESCs are reporting their status.

@@ -1610,6 +1614,18 @@ Commander::run()
}
}

if (orb_exists(ORB_ID(esc_status), 0) == PX4_OK) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you really need this? Is it not enough to check if it's updated and the timestamp is valid?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are right, this is a left over that I introduced then the logic was still reasoning on "is valid" and thus i needed to initialize that to true in case of escs not reporting status. Changing the message to condition_escs_error (and thus inverting the logic) automatically solved this corner case. Will get rid of that

src/modules/commander/Commander.cpp Show resolved Hide resolved
else if (esc_status.esc_online_flags < _last_esc_online_flags) {

for (int index = 0; index < esc_status.esc_count; index++) {
if ((bool)!(esc_status.esc_online_flags & (1 << index))) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if ((bool)!(esc_status.esc_online_flags & (1 << index))) {
if ((esc_status.esc_online_flags & (1 << index)) == 0) {

@dagar
Copy link
Member

dagar commented Aug 6, 2019

How about a simple boolean parameter like COM_ARM_MIS_REQ rather than a circuit breaker and magic number? At some point I was going to try rolling all the pre-arming checks into a single bitfield parameter.

@cmic0
Copy link
Contributor Author

cmic0 commented Aug 7, 2019

@dagar thanks for the hint will have a look


for (int index = 0; index < esc_status_s::CONNECTED_ESC_MAX; index++) {

if (hrt_elapsed_time(&_esc_status.esc[index].timestamp) < 800000.0f && _esc_status.esc[index].timestamp > 0) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if you reverse the order of the two statements you can avoid the (presumably more expensive) hrt_elapsed_time() call when the timestamp is invalid.

@cmic0 cmic0 force-pushed the escstatus_checks_clean branch from c54e76a to e7e0769 Compare August 8, 2019 10:16
@cmic0
Copy link
Contributor Author

cmic0 commented Aug 8, 2019

@bkueng thanks for the review, all your comments have been addressed; I think the PR is now ready to go.
FYI: I cleaned up the commit history with the last push :)

src/modules/commander/Commander.cpp Show resolved Hide resolved
src/modules/commander/Commander.cpp Show resolved Hide resolved
bool circuit_breaker_engaged_power_check
bool circuit_breaker_engaged_airspd_check
bool circuit_breaker_engaged_enginefailure_check
bool circuit_breaker_engaged_gpsfailure_check
bool circuit_breaker_flight_termination_disabled
bool circuit_breaker_engaged_usb_check
bool circuit_breaker_engaged_posfailure_check # set to true when the position valid checks have been disabled
bool circuit_breaker_engaged_escs_check
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since it's not a circuit breaker anymore, can you rename this as well?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correct this can actually be removed.


for (int index = 0; index < esc_status_s::CONNECTED_ESC_MAX; index++) {

if (_esc_status.esc[index].timestamp > 0 && hrt_elapsed_time(&_esc_status.esc[index].timestamp) < 800000.0f) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2 more things you can do here: pull the hrt_absolute_time call out of the loop: hrt_abstime now = hrt_absolute_time();, and use the time literals: now - _esc_status.esc[index].timestamp < 800_ms) {
(add using namespace time_literals; at the top of the file).

@cmic0 cmic0 force-pushed the escstatus_checks_clean branch from 1add79e to b7d489e Compare August 8, 2019 15:42
@bkueng bkueng merged commit aae16cc into PX4:master Aug 9, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants