esc_report: add actuator_function

This commit is contained in:
Beat Küng
2022-01-24 11:20:27 +01:00
parent aab2feb8f5
commit dfd934fbdb
9 changed files with 35 additions and 13 deletions
+2
View File
@@ -4,6 +4,8 @@ uint64 timestamp_sample # the timestamp the data this control response is ba
uint16 reversible_flags # bitset which motors are configured to be reversible uint16 reversible_flags # bitset which motors are configured to be reversible
uint8 ACTUATOR_FUNCTION_MOTOR1 = 101
uint8 NUM_CONTROLS = 12 uint8 NUM_CONTROLS = 12
float32[12] control # range: [-1, 1], where 1 means maximum positive thrust, float32[12] control # range: [-1, 1], where 1 means maximum positive thrust,
# -1 maximum negative (if not supported by the output, <0 maps to NaN), # -1 maximum negative (if not supported by the output, <0 maps to NaN),
+2
View File
@@ -8,6 +8,8 @@ uint8 esc_address # Address of current ESC (in most cases 1-8 / must be set
uint8 esc_state # State of ESC - depend on Vendor uint8 esc_state # State of ESC - depend on Vendor
uint8 actuator_function # actuator output function (one of Motor1...MotorN)
uint16 failures # Bitmask to indicate the internal ESC faults uint16 failures # Bitmask to indicate the internal ESC faults
uint8 FAILURE_OVER_CURRENT = 0 # (1 << 0) uint8 FAILURE_OVER_CURRENT = 0 # (1 << 0)
+16 -11
View File
@@ -247,7 +247,10 @@ void DShot::update_telemetry_num_motors()
if (_mixing_output.useDynamicMixing()) { if (_mixing_output.useDynamicMixing()) {
for (unsigned i = 0; i < _num_outputs; ++i) { for (unsigned i = 0; i < _num_outputs; ++i) {
motor_count += _mixing_output.isFunctionSet(i); if (_mixing_output.isFunctionSet(i)) {
_telemetry->actuator_functions[motor_count] = (uint8_t)_mixing_output.outputFunction(i);
++motor_count;
}
} }
} else { } else {
@@ -281,24 +284,26 @@ void DShot::init_telemetry(const char *device)
update_telemetry_num_motors(); update_telemetry_num_motors();
} }
void DShot::handle_new_telemetry_data(const int motor_index, const DShotTelemetry::EscData &data) void DShot::handle_new_telemetry_data(const int telemetry_index, const DShotTelemetry::EscData &data)
{ {
// fill in new motor data // fill in new motor data
esc_status_s &esc_status = _telemetry->esc_status_pub.get(); esc_status_s &esc_status = _telemetry->esc_status_pub.get();
if (motor_index < esc_status_s::CONNECTED_ESC_MAX) { if (telemetry_index < esc_status_s::CONNECTED_ESC_MAX) {
esc_status.esc_online_flags |= 1 << motor_index; esc_status.esc_online_flags |= 1 << telemetry_index;
esc_status.esc[motor_index].timestamp = data.time; esc_status.esc[telemetry_index].actuator_function = _telemetry->actuator_functions[telemetry_index];
esc_status.esc[motor_index].esc_rpm = (static_cast<int>(data.erpm) * 100) / (_param_mot_pole_count.get() / 2); esc_status.esc[telemetry_index].timestamp = data.time;
esc_status.esc[motor_index].esc_voltage = static_cast<float>(data.voltage) * 0.01f; esc_status.esc[telemetry_index].esc_rpm = (static_cast<int>(data.erpm) * 100) /
esc_status.esc[motor_index].esc_current = static_cast<float>(data.current) * 0.01f; (_param_mot_pole_count.get() / 2);
esc_status.esc[motor_index].esc_temperature = static_cast<float>(data.temperature); esc_status.esc[telemetry_index].esc_voltage = static_cast<float>(data.voltage) * 0.01f;
esc_status.esc[telemetry_index].esc_current = static_cast<float>(data.current) * 0.01f;
esc_status.esc[telemetry_index].esc_temperature = static_cast<float>(data.temperature);
// TODO: accumulate consumption and use for battery estimation // TODO: accumulate consumption and use for battery estimation
} }
// publish when motor index wraps (which is robust against motor timeouts) // publish when motor index wraps (which is robust against motor timeouts)
if (motor_index <= _telemetry->last_motor_index) { if (telemetry_index <= _telemetry->last_telemetry_index) {
esc_status.timestamp = hrt_absolute_time(); esc_status.timestamp = hrt_absolute_time();
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();
@@ -314,7 +319,7 @@ void DShot::handle_new_telemetry_data(const int motor_index, const DShotTelemetr
esc_status.esc_online_flags = 0; esc_status.esc_online_flags = 0;
} }
_telemetry->last_motor_index = motor_index; _telemetry->last_telemetry_index = telemetry_index;
} }
int DShot::send_command_thread_safe(const dshot_command_t command, const int num_repetitions, const int motor_index) int DShot::send_command_thread_safe(const dshot_command_t command, const int num_repetitions, const int motor_index)
+3 -2
View File
@@ -127,14 +127,15 @@ private:
struct Telemetry { struct Telemetry {
DShotTelemetry handler{}; DShotTelemetry handler{};
uORB::PublicationMultiData<esc_status_s> esc_status_pub{ORB_ID(esc_status)}; uORB::PublicationMultiData<esc_status_s> esc_status_pub{ORB_ID(esc_status)};
int last_motor_index{-1}; int last_telemetry_index{-1};
uint8_t actuator_functions[esc_status_s::CONNECTED_ESC_MAX] {};
}; };
void enable_dshot_outputs(const bool enabled); void enable_dshot_outputs(const bool enabled);
void init_telemetry(const char *device); void init_telemetry(const char *device);
void handle_new_telemetry_data(const int motor_index, const DShotTelemetry::EscData &data); void handle_new_telemetry_data(const int telemetry_index, const DShotTelemetry::EscData &data);
int request_esc_info(); int request_esc_info();
+2
View File
@@ -290,6 +290,8 @@ bool TAP_ESC::updateOutputs(bool stop_motors, uint16_t outputs[MAX_ACTUATORS], u
if (feed_back_data.channelID < esc_status_s::CONNECTED_ESC_MAX) { if (feed_back_data.channelID < esc_status_s::CONNECTED_ESC_MAX) {
_esc_feedback.esc[feed_back_data.channelID].timestamp = hrt_absolute_time(); _esc_feedback.esc[feed_back_data.channelID].timestamp = hrt_absolute_time();
_esc_feedback.esc[feed_back_data.channelID].actuator_function = (uint8_t)_mixing_output.outputFunction(
feed_back_data.channelID);
_esc_feedback.esc[feed_back_data.channelID].esc_errorcount = 0; _esc_feedback.esc[feed_back_data.channelID].esc_errorcount = 0;
_esc_feedback.esc[feed_back_data.channelID].esc_rpm = feed_back_data.speed; _esc_feedback.esc[feed_back_data.channelID].esc_rpm = feed_back_data.speed;
#if defined(ESC_HAVE_VOLTAGE_SENSOR) #if defined(ESC_HAVE_VOLTAGE_SENSOR)
+2
View File
@@ -48,6 +48,7 @@
#include <uORB/topics/airspeed.h> #include <uORB/topics/airspeed.h>
#include <uORB/topics/battery_status.h> #include <uORB/topics/battery_status.h>
#include <uORB/topics/esc_status.h> #include <uORB/topics/esc_status.h>
#include <uORB/topics/actuator_motors.h>
#include <uORB/topics/home_position.h> #include <uORB/topics/home_position.h>
#include <uORB/topics/vehicle_air_data.h> #include <uORB/topics/vehicle_air_data.h>
#include <uORB/topics/vehicle_gps_position.h> #include <uORB/topics/vehicle_gps_position.h>
@@ -114,6 +115,7 @@ publish_gam_message(const uint8_t *buffer)
esc.esc_count = 1; esc.esc_count = 1;
esc.esc_connectiontype = esc_status_s::ESC_CONNECTION_TYPE_PPM; esc.esc_connectiontype = esc_status_s::ESC_CONNECTION_TYPE_PPM;
esc.esc[0].actuator_function = actuator_motors_s::ACTUATOR_FUNCTION_MOTOR1;
esc.esc[0].esc_rpm = (uint16_t)((msg.rpm_H << 8) | (msg.rpm_L & 0xff)) * 10; esc.esc[0].esc_rpm = (uint16_t)((msg.rpm_H << 8) | (msg.rpm_L & 0xff)) * 10;
esc.esc[0].esc_temperature = static_cast<float>(msg.temperature1 - 20); esc.esc[0].esc_temperature = static_cast<float>(msg.temperature1 - 20);
esc.esc[0].esc_voltage = static_cast<float>((msg.main_voltage_H << 8) | (msg.main_voltage_L & 0xff)) * 0.1F; esc.esc[0].esc_voltage = static_cast<float>((msg.main_voltage_H << 8) | (msg.main_voltage_L & 0xff)) * 0.1F;
+2
View File
@@ -78,6 +78,8 @@ public:
static int max_output_value() { return uavcan::equipment::esc::RawCommand::FieldTypes::cmd::RawValueType::max(); } static int max_output_value() { return uavcan::equipment::esc::RawCommand::FieldTypes::cmd::RawValueType::max(); }
esc_status_s &esc_status() { return _esc_status; }
private: private:
/** /**
* ESC status message reception will be reported via this callback. * ESC status message reception will be reported via this callback.
+4
View File
@@ -1003,6 +1003,10 @@ void UavcanMixingInterfaceESC::mixerChanged()
if (_mixing_output.useDynamicMixing()) { if (_mixing_output.useDynamicMixing()) {
for (unsigned i = 0; i < MAX_ACTUATORS; ++i) { for (unsigned i = 0; i < MAX_ACTUATORS; ++i) {
rotor_count += _mixing_output.isFunctionSet(i); rotor_count += _mixing_output.isFunctionSet(i);
if (i < esc_status_s::CONNECTED_ESC_MAX) {
_esc_controller.esc_status().esc[i].actuator_function = (uint8_t)_mixing_output.outputFunction(i);
}
} }
} else { } else {
+2
View File
@@ -116,6 +116,8 @@ public:
static_assert(actuator_motors_s::NUM_CONTROLS == (int)OutputFunction::MotorMax - (int)OutputFunction::Motor1 + 1, static_assert(actuator_motors_s::NUM_CONTROLS == (int)OutputFunction::MotorMax - (int)OutputFunction::Motor1 + 1,
"Unexpected num motors"); "Unexpected num motors");
static_assert(actuator_motors_s::ACTUATOR_FUNCTION_MOTOR1 == (int)OutputFunction::Motor1, "Unexpected motor idx");
FunctionMotors(const Context &context); FunctionMotors(const Context &context);
static FunctionProviderBase *allocate(const Context &context) { return new FunctionMotors(context); } static FunctionProviderBase *allocate(const Context &context) { return new FunctionMotors(context); }