8 changed files with 223 additions and 7 deletions
@ -0,0 +1,169 @@ |
|||||||
|
#include <AP_HAL/AP_HAL.h> |
||||||
|
|
||||||
|
#include "AP_EFI_DroneCAN.h" |
||||||
|
|
||||||
|
#if HAL_EFI_DRONECAN_ENABLED |
||||||
|
|
||||||
|
#include <AP_CANManager/AP_CANManager.h> |
||||||
|
#include <AP_UAVCAN/AP_UAVCAN.h> |
||||||
|
|
||||||
|
#include <uavcan/equipment/ice/reciprocating/Status.hpp> |
||||||
|
|
||||||
|
extern const AP_HAL::HAL& hal; |
||||||
|
|
||||||
|
AP_EFI_DroneCAN *AP_EFI_DroneCAN::driver; |
||||||
|
|
||||||
|
// DroneCAN Frontend Registry Binder
|
||||||
|
UC_REGISTRY_BINDER(EFIStatusCb, uavcan::equipment::ice::reciprocating::Status); |
||||||
|
|
||||||
|
// constructor
|
||||||
|
AP_EFI_DroneCAN::AP_EFI_DroneCAN(AP_EFI &_frontend) : |
||||||
|
AP_EFI_Backend(_frontend) |
||||||
|
{ |
||||||
|
driver = this; |
||||||
|
} |
||||||
|
|
||||||
|
// links the DroneCAN message to this backend
|
||||||
|
void AP_EFI_DroneCAN::subscribe_msgs(AP_UAVCAN *ap_uavcan) |
||||||
|
{ |
||||||
|
if (ap_uavcan == nullptr) { |
||||||
|
return; |
||||||
|
} |
||||||
|
auto* node = ap_uavcan->get_node(); |
||||||
|
|
||||||
|
uavcan::Subscriber<uavcan::equipment::ice::reciprocating::Status, EFIStatusCb> *status_listener; |
||||||
|
status_listener = new uavcan::Subscriber<uavcan::equipment::ice::reciprocating::Status, EFIStatusCb>(*node); |
||||||
|
|
||||||
|
// Register method to handle incoming status
|
||||||
|
const int status_listener_res = status_listener->start(EFIStatusCb(ap_uavcan, &trampoline_status)); |
||||||
|
if (status_listener_res < 0) { |
||||||
|
AP_HAL::panic("DroneCAN EFI subscriber start problem\n\r"); |
||||||
|
return; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// Called from frontend to update with the readings received by handler
|
||||||
|
void AP_EFI_DroneCAN::update() |
||||||
|
{ |
||||||
|
} |
||||||
|
|
||||||
|
// EFI message handler
|
||||||
|
void AP_EFI_DroneCAN::trampoline_status(AP_UAVCAN *ap_uavcan, uint8_t node_id, const EFIStatusCb &cb) |
||||||
|
{ |
||||||
|
if (driver == nullptr) { |
||||||
|
return; |
||||||
|
} |
||||||
|
const uavcan::equipment::ice::reciprocating::Status &pkt = *cb.msg; |
||||||
|
driver->handle_status(pkt); |
||||||
|
} |
||||||
|
|
||||||
|
/*
|
||||||
|
handle reciprocating ICE status message from DroneCAN |
||||||
|
*/ |
||||||
|
void AP_EFI_DroneCAN::handle_status(const uavcan::equipment::ice::reciprocating::Status &pkt) |
||||||
|
{ |
||||||
|
auto &istate = internal_state; |
||||||
|
|
||||||
|
// state maps 1:1 from Engine_State
|
||||||
|
istate.engine_state = Engine_State(pkt.state); |
||||||
|
|
||||||
|
if (!(pkt.flags & uavcan::equipment::ice::reciprocating::Status::FLAG_CRANKSHAFT_SENSOR_ERROR_SUPPORTED)) { |
||||||
|
istate.crankshaft_sensor_status = Crankshaft_Sensor_Status::NOT_SUPPORTED; |
||||||
|
} else if (pkt.flags & uavcan::equipment::ice::reciprocating::Status::FLAG_CRANKSHAFT_SENSOR_ERROR) { |
||||||
|
istate.crankshaft_sensor_status = Crankshaft_Sensor_Status::ERROR; |
||||||
|
} else { |
||||||
|
istate.crankshaft_sensor_status = Crankshaft_Sensor_Status::OK; |
||||||
|
} |
||||||
|
|
||||||
|
if (!(pkt.flags & uavcan::equipment::ice::reciprocating::Status::FLAG_TEMPERATURE_SUPPORTED)) { |
||||||
|
istate.temperature_status = Temperature_Status::NOT_SUPPORTED; |
||||||
|
} else if (pkt.flags & uavcan::equipment::ice::reciprocating::Status::FLAG_TEMPERATURE_BELOW_NOMINAL) { |
||||||
|
istate.temperature_status = Temperature_Status::BELOW_NOMINAL; |
||||||
|
} else if (pkt.flags & uavcan::equipment::ice::reciprocating::Status::FLAG_TEMPERATURE_ABOVE_NOMINAL) { |
||||||
|
istate.temperature_status = Temperature_Status::ABOVE_NOMINAL; |
||||||
|
} else if (pkt.flags & uavcan::equipment::ice::reciprocating::Status::FLAG_TEMPERATURE_OVERHEATING) { |
||||||
|
istate.temperature_status = Temperature_Status::OVERHEATING; |
||||||
|
} else if (pkt.flags & uavcan::equipment::ice::reciprocating::Status::FLAG_TEMPERATURE_EGT_ABOVE_NOMINAL) { |
||||||
|
istate.temperature_status = Temperature_Status::EGT_ABOVE_NOMINAL; |
||||||
|
} else { |
||||||
|
istate.temperature_status = Temperature_Status::OK; |
||||||
|
} |
||||||
|
|
||||||
|
if (!(pkt.flags & uavcan::equipment::ice::reciprocating::Status::FLAG_FUEL_PRESSURE_SUPPORTED)) { |
||||||
|
istate.fuel_pressure_status = Fuel_Pressure_Status::NOT_SUPPORTED; |
||||||
|
} else if (pkt.flags & uavcan::equipment::ice::reciprocating::Status::FLAG_FUEL_PRESSURE_BELOW_NOMINAL) { |
||||||
|
istate.fuel_pressure_status = Fuel_Pressure_Status::BELOW_NOMINAL; |
||||||
|
} else if (pkt.flags & uavcan::equipment::ice::reciprocating::Status::FLAG_FUEL_PRESSURE_ABOVE_NOMINAL) { |
||||||
|
istate.fuel_pressure_status = Fuel_Pressure_Status::ABOVE_NOMINAL; |
||||||
|
} else { |
||||||
|
istate.fuel_pressure_status = Fuel_Pressure_Status::OK; |
||||||
|
} |
||||||
|
|
||||||
|
if (!(pkt.flags & uavcan::equipment::ice::reciprocating::Status::FLAG_OIL_PRESSURE_SUPPORTED)) { |
||||||
|
istate.oil_pressure_status = Oil_Pressure_Status::NOT_SUPPORTED; |
||||||
|
} else if (pkt.flags & uavcan::equipment::ice::reciprocating::Status::FLAG_OIL_PRESSURE_BELOW_NOMINAL) { |
||||||
|
istate.oil_pressure_status = Oil_Pressure_Status::BELOW_NOMINAL; |
||||||
|
} else if (pkt.flags & uavcan::equipment::ice::reciprocating::Status::FLAG_OIL_PRESSURE_ABOVE_NOMINAL) { |
||||||
|
istate.oil_pressure_status = Oil_Pressure_Status::ABOVE_NOMINAL; |
||||||
|
} else { |
||||||
|
istate.oil_pressure_status = Oil_Pressure_Status::OK; |
||||||
|
} |
||||||
|
|
||||||
|
if (!(pkt.flags & uavcan::equipment::ice::reciprocating::Status::FLAG_DETONATION_SUPPORTED)) { |
||||||
|
istate.detonation_status = Detonation_Status::NOT_SUPPORTED; |
||||||
|
} else if (pkt.flags & uavcan::equipment::ice::reciprocating::Status::FLAG_DETONATION_OBSERVED) { |
||||||
|
istate.detonation_status = Detonation_Status::OBSERVED; |
||||||
|
} else { |
||||||
|
istate.detonation_status = Detonation_Status::NOT_OBSERVED; |
||||||
|
} |
||||||
|
|
||||||
|
if (!(pkt.flags & uavcan::equipment::ice::reciprocating::Status::FLAG_MISFIRE_SUPPORTED)) { |
||||||
|
istate.misfire_status = Misfire_Status::NOT_SUPPORTED; |
||||||
|
} else if (pkt.flags & uavcan::equipment::ice::reciprocating::Status::FLAG_MISFIRE_OBSERVED) { |
||||||
|
istate.misfire_status = Misfire_Status::OBSERVED; |
||||||
|
} else { |
||||||
|
istate.misfire_status = Misfire_Status::NOT_OBSERVED; |
||||||
|
} |
||||||
|
|
||||||
|
if (!(pkt.flags & uavcan::equipment::ice::reciprocating::Status::FLAG_DEBRIS_SUPPORTED)) { |
||||||
|
istate.debris_status = Debris_Status::NOT_SUPPORTED; |
||||||
|
} else if (pkt.flags & uavcan::equipment::ice::reciprocating::Status::FLAG_DEBRIS_DETECTED) { |
||||||
|
istate.debris_status = Debris_Status::DETECTED; |
||||||
|
} else { |
||||||
|
istate.debris_status = Debris_Status::NOT_DETECTED; |
||||||
|
} |
||||||
|
|
||||||
|
istate.engine_load_percent = pkt.engine_load_percent; |
||||||
|
istate.engine_speed_rpm = pkt.engine_speed_rpm; |
||||||
|
istate.spark_dwell_time_ms = pkt.spark_dwell_time_ms; |
||||||
|
istate.atmospheric_pressure_kpa = pkt.atmospheric_pressure_kpa; |
||||||
|
istate.intake_manifold_pressure_kpa = pkt.intake_manifold_pressure_kpa; |
||||||
|
istate.intake_manifold_temperature = pkt.intake_manifold_temperature; |
||||||
|
istate.coolant_temperature = pkt.coolant_temperature; |
||||||
|
istate.oil_pressure = pkt.oil_pressure; |
||||||
|
istate.oil_temperature = pkt.oil_temperature; |
||||||
|
istate.fuel_pressure = pkt.fuel_pressure; |
||||||
|
istate.fuel_consumption_rate_cm3pm = pkt.fuel_consumption_rate_cm3pm; |
||||||
|
istate.estimated_consumed_fuel_volume_cm3 = pkt.estimated_consumed_fuel_volume_cm3; |
||||||
|
istate.throttle_position_percent = pkt.throttle_position_percent; |
||||||
|
istate.ecu_index = pkt.ecu_index; |
||||||
|
|
||||||
|
// 1:1 for spark plug usage
|
||||||
|
istate.spark_plug_usage = Spark_Plug_Usage(pkt.spark_plug_usage); |
||||||
|
|
||||||
|
// assume max one cylinder status
|
||||||
|
if (pkt.cylinder_status.size() > 0) { |
||||||
|
const auto &cs = pkt.cylinder_status[0]; |
||||||
|
auto &c = istate.cylinder_status[0]; |
||||||
|
c.ignition_timing_deg = cs.ignition_timing_deg; |
||||||
|
c.injection_time_ms = cs.injection_time_ms; |
||||||
|
c.cylinder_head_temperature = cs.cylinder_head_temperature; |
||||||
|
c.exhaust_gas_temperature = cs.exhaust_gas_temperature; |
||||||
|
c.lambda_coefficient = cs.lambda_coefficient; |
||||||
|
} |
||||||
|
|
||||||
|
copy_to_frontend(); |
||||||
|
} |
||||||
|
|
||||||
|
#endif // HAL_EFI_DRONECAN_ENABLED
|
||||||
|
|
@ -0,0 +1,32 @@ |
|||||||
|
#pragma once |
||||||
|
|
||||||
|
#include "AP_EFI.h" |
||||||
|
#include "AP_EFI_Backend.h" |
||||||
|
|
||||||
|
#ifndef HAL_EFI_DRONECAN_ENABLED |
||||||
|
#define HAL_EFI_DRONECAN_ENABLED HAL_MAX_CAN_PROTOCOL_DRIVERS && BOARD_FLASH_SIZE > 1024 && HAL_CANMANAGER_ENABLED |
||||||
|
#endif |
||||||
|
|
||||||
|
#if HAL_EFI_DRONECAN_ENABLED |
||||||
|
#include <AP_UAVCAN/AP_UAVCAN.h> |
||||||
|
#include <uavcan/equipment/ice/reciprocating/Status.hpp> |
||||||
|
|
||||||
|
class EFIStatusCb; |
||||||
|
|
||||||
|
class AP_EFI_DroneCAN : public AP_EFI_Backend { |
||||||
|
public: |
||||||
|
AP_EFI_DroneCAN(AP_EFI &_frontend); |
||||||
|
|
||||||
|
void update() override; |
||||||
|
|
||||||
|
static void subscribe_msgs(AP_UAVCAN* ap_uavcan); |
||||||
|
static void trampoline_status(AP_UAVCAN* ap_uavcan, uint8_t node_id, const EFIStatusCb &cb); |
||||||
|
|
||||||
|
private: |
||||||
|
void handle_status(const uavcan::equipment::ice::reciprocating::Status &pkt); |
||||||
|
|
||||||
|
// singleton for trampoline
|
||||||
|
static AP_EFI_DroneCAN *driver; |
||||||
|
}; |
||||||
|
#endif // HAL_EFI_DRONECAN_ENABLED
|
||||||
|
|
Loading…
Reference in new issue