mirror of
https://gitee.com/mirrors_PX4/PX4-Autopilot.git
synced 2026-10-25 03:33:35 +08:00
dshot: bdshot fix esc offline/online checks
This commit is contained in:
committed by
David Sidrane
parent
0e41f9730f
commit
5d2fda6172
@@ -86,8 +86,11 @@ typedef struct dshot_handler_t {
|
|||||||
uint32_t crc_error_cnt;
|
uint32_t crc_error_cnt;
|
||||||
uint32_t frame_error_cnt;
|
uint32_t frame_error_cnt;
|
||||||
uint32_t no_response_cnt;
|
uint32_t no_response_cnt;
|
||||||
|
uint32_t last_no_response_cnt;
|
||||||
} dshot_handler_t;
|
} dshot_handler_t;
|
||||||
|
|
||||||
|
#define BDSHOT_OFFLINE_COUNT 400 // If there are no responses for 400 setpoints ESC is offline
|
||||||
|
|
||||||
static dshot_handler_t dshot_inst[DSHOT_TIMERS] = {};
|
static dshot_handler_t dshot_inst[DSHOT_TIMERS] = {};
|
||||||
|
|
||||||
static uint32_t dshot_tcmp;
|
static uint32_t dshot_tcmp;
|
||||||
@@ -390,6 +393,7 @@ void up_bdshot_erpm(void)
|
|||||||
} else {
|
} else {
|
||||||
dshot_inst[channel].erpm = ~(erpm >> 4) & 0xFFF;
|
dshot_inst[channel].erpm = ~(erpm >> 4) & 0xFFF;
|
||||||
bdshot_parsed_recv_mask |= (1 << channel);
|
bdshot_parsed_recv_mask |= (1 << channel);
|
||||||
|
dshot_inst[channel].last_no_response_cnt = dshot_inst[channel].no_response_cnt;
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
@@ -411,6 +415,14 @@ int up_bdshot_get_erpm(uint8_t channel, int *erpm)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int up_bdshot_channel_status(uint8_t channel)
|
||||||
|
{
|
||||||
|
if (channel < DSHOT_TIMERS) {
|
||||||
|
return ((dshot_inst[channel].no_response_cnt - dshot_inst[channel].last_no_response_cnt) < BDSHOT_OFFLINE_COUNT);
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
void up_bdshot_status(void)
|
void up_bdshot_status(void)
|
||||||
{
|
{
|
||||||
@@ -418,7 +430,8 @@ void up_bdshot_status(void)
|
|||||||
for (uint8_t channel = 0; (channel < DSHOT_TIMERS); channel++) {
|
for (uint8_t channel = 0; (channel < DSHOT_TIMERS); channel++) {
|
||||||
|
|
||||||
if (dshot_inst[channel].init) {
|
if (dshot_inst[channel].init) {
|
||||||
PX4_INFO("Channel %i Last erpm %i value", channel, dshot_inst[channel].erpm);
|
PX4_INFO("Channel %i %s Last erpm %i value", channel, up_bdshot_channel_status(channel) ? "online" : "offline",
|
||||||
|
dshot_inst[channel].erpm);
|
||||||
PX4_INFO("CRC errors Frame error No response");
|
PX4_INFO("CRC errors Frame error No response");
|
||||||
PX4_INFO("%10lu %11lu %11lu", dshot_inst[channel].crc_error_cnt, dshot_inst[channel].frame_error_cnt,
|
PX4_INFO("%10lu %11lu %11lu", dshot_inst[channel].crc_error_cnt, dshot_inst[channel].frame_error_cnt,
|
||||||
dshot_inst[channel].no_response_cnt);
|
dshot_inst[channel].no_response_cnt);
|
||||||
|
|||||||
@@ -158,6 +158,12 @@ int up_bdshot_get_erpm(uint8_t channel, int *erpm)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int up_bdshot_channel_status(uint8_t channel)
|
||||||
|
{
|
||||||
|
// Not implemented
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
void up_bdshot_status(void)
|
void up_bdshot_status(void)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -152,4 +152,13 @@ __EXPORT extern void up_bdshot_status(void);
|
|||||||
__EXPORT extern int up_bdshot_get_erpm(uint8_t channel, int *erpm);
|
__EXPORT extern int up_bdshot_get_erpm(uint8_t channel, int *erpm);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get bidrectional dshot status for a channel
|
||||||
|
* @param channel Dshot channel
|
||||||
|
* @param erpm pointer to write the erpm value
|
||||||
|
* @return <0 on error / not supported, 0 on offline, 1 on online
|
||||||
|
*/
|
||||||
|
__EXPORT extern int up_bdshot_channel_status(uint8_t channel);
|
||||||
|
|
||||||
|
|
||||||
__END_DECLS
|
__END_DECLS
|
||||||
|
|||||||
@@ -159,6 +159,9 @@ void DShot::enable_dshot_outputs(const bool enabled)
|
|||||||
for (unsigned i = 0; i < _num_outputs; ++i) {
|
for (unsigned i = 0; i < _num_outputs; ++i) {
|
||||||
if (((1 << i) & _output_mask) == 0) {
|
if (((1 << i) & _output_mask) == 0) {
|
||||||
_mixing_output.disableFunction(i);
|
_mixing_output.disableFunction(i);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
_dshot_esc_count++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -248,9 +251,6 @@ int DShot::handle_new_telemetry_data(const int telemetry_index, const DShotTelem
|
|||||||
esc_status.esc_connectiontype = esc_status_s::ESC_CONNECTION_TYPE_DSHOT;
|
esc_status.esc_connectiontype = esc_status_s::ESC_CONNECTION_TYPE_DSHOT;
|
||||||
esc_status.esc_count = _telemetry->handler.numMotors();
|
esc_status.esc_count = _telemetry->handler.numMotors();
|
||||||
++esc_status.counter;
|
++esc_status.counter;
|
||||||
// FIXME: mark all ESC's as online, otherwise commander complains even for a single dropout
|
|
||||||
esc_status.esc_online_flags = (1 << esc_status.esc_count) - 1;
|
|
||||||
esc_status.esc_armed_flags = (1 << esc_status.esc_count) - 1;
|
|
||||||
|
|
||||||
ret = 1; // Indicate we wrapped, so we publish data
|
ret = 1; // Indicate we wrapped, so we publish data
|
||||||
}
|
}
|
||||||
@@ -263,14 +263,31 @@ int DShot::handle_new_telemetry_data(const int telemetry_index, const DShotTelem
|
|||||||
void DShot::publish_esc_status(void)
|
void DShot::publish_esc_status(void)
|
||||||
{
|
{
|
||||||
esc_status_s &esc_status = _telemetry->esc_status_pub.get();
|
esc_status_s &esc_status = _telemetry->esc_status_pub.get();
|
||||||
|
uint8_t channel;
|
||||||
|
|
||||||
// clear data of the esc that are offline
|
// clear data of the esc that are offline
|
||||||
for (uint8_t channel = 0; (channel < _telemetry->last_telemetry_index); channel++) {
|
for (channel = 0; (channel < _telemetry->last_telemetry_index); channel++) {
|
||||||
if ((esc_status.esc_online_flags & (1 << channel)) == 0) {
|
if ((esc_status.esc_online_flags & (1 << channel)) == 0) {
|
||||||
memset(&esc_status.esc[channel], 0, sizeof(struct esc_report_s));
|
memset(&esc_status.esc[channel], 0, sizeof(struct esc_report_s));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FIXME: mark all UART Telemetry ESC's as online, otherwise commander complains even for a single dropout
|
||||||
|
esc_status.esc_online_flags = (1 << esc_status.esc_count) - 1;
|
||||||
|
esc_status.esc_armed_flags = (1 << esc_status.esc_count) - 1;
|
||||||
|
|
||||||
|
if (_bdshot) {
|
||||||
|
esc_status.esc_online_flags |= _output_mask;
|
||||||
|
esc_status.esc_armed_flags |= _output_mask;
|
||||||
|
esc_status.esc_count = _dshot_esc_count;
|
||||||
|
|
||||||
|
for (channel = 0; (channel < 8); channel++) {
|
||||||
|
if (up_bdshot_channel_status(channel) == 0) {
|
||||||
|
esc_status.esc_online_flags &= ~(1 << channel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ESC telem wrap around or bdshot update
|
// ESC telem wrap around or bdshot update
|
||||||
_telemetry->esc_status_pub.update();
|
_telemetry->esc_status_pub.update();
|
||||||
|
|
||||||
@@ -302,8 +319,6 @@ int DShot::handle_new_bdshot_erpm(void)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
esc_status.esc_count = num_erpms;
|
|
||||||
|
|
||||||
return num_erpms;
|
return num_erpms;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -780,7 +795,9 @@ int DShot::print_status()
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Print dshot status */
|
/* Print dshot status */
|
||||||
up_bdshot_status();
|
if (_bdshot) {
|
||||||
|
up_bdshot_status();
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -166,6 +166,7 @@ private:
|
|||||||
|
|
||||||
static constexpr unsigned _num_outputs{DIRECT_PWM_OUTPUT_CHANNELS};
|
static constexpr unsigned _num_outputs{DIRECT_PWM_OUTPUT_CHANNELS};
|
||||||
uint32_t _output_mask{0};
|
uint32_t _output_mask{0};
|
||||||
|
uint32_t _dshot_esc_count{0};
|
||||||
|
|
||||||
perf_counter_t _cycle_perf{perf_alloc(PC_ELAPSED, MODULE_NAME": cycle")};
|
perf_counter_t _cycle_perf{perf_alloc(PC_ELAPSED, MODULE_NAME": cycle")};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user