Summary
The DroneCAN BatteryInfo message contains comprehensive SOC data that INAV currently ignores. Implementing SOC support would allow smart batteries to report their actual state of charge instead of relying on current integration.
Problem
Current implementation only extracts voltage and current:
// sensors/battery_sensor_dronecan.c
void dronecanBatterySensorReceiveInfo(struct uavcan_equipment_power_BatteryInfo *pbatteryInfo)
{
dronecanVbat = (uint16_t)roundf(pbatteryInfo->voltage * 100.0F); // centivolts
dronecanAmperage = (uint16_t)roundf(pbatteryInfo->current * 100.0F); // centiamps
// All SOC fields IGNORED
};
Available DroneCAN BatteryInfo Fields
struct uavcan_equipment_power_BatteryInfo {
float temperature; // Battery temperature (Kelvin)
float voltage; // ✅ Used - Pack voltage (V)
float current; // ✅ Used - Current draw (A)
float average_power_10sec; // ❌ Ignored - Average power
float remaining_capacity_wh; // ❌ Ignored - Remaining energy (Wh)
float full_charge_capacity_wh; // ❌ Ignored - Full capacity (Wh)
float hours_to_full_charge; // ❌ Ignored - Time to full
uint16_t status_flags; // ❌ Ignored - Status flags
uint8_t state_of_health_pct; // ❌ Ignored - Battery health %
uint8_t state_of_charge_pct; // ❌ Ignored - SOC % (0-100)
uint8_t state_of_charge_pct_stdev; // ❌ Ignored - SOC uncertainty
uint8_t battery_id; // ❌ Ignored - Multi-battery ID
// ...
};
Solution
Add a new setting following the existing pattern:
- name: battery_capacity_source
description: "Source for battery remaining capacity. ADC=current integration, CAN=DroneCAN BMS reported"
default_value: "ADC"
field: capacity_source
table: capacity_source_type
type: uint8_t
New enum:
typedef enum {
BAT_CAPACITY_SOURCE_ADC = 0, // Current integration (default)
BAT_CAPACITY_SOURCE_CAN = 1, // DroneCAN BMS reported
} batCapacitySource_e;
Implementation Approach
Hybrid (recommended):
if (remaining_capacity_wh > 0 && full_charge_capacity_wh > 0) {
// Use Wh-based (more accurate)
} else if (state_of_charge_pct > 0) {
// Use percentage (fallback)
} else {
// Use current integration (last resort)
}
Effort Estimate
3-5 hours
Files to Modify
| File |
Changes |
sensors/battery_sensor_dronecan.c |
Add SOC extraction and getters |
sensors/battery_sensor_dronecan.h |
Add getter prototypes |
sensors/battery.c |
Add capacity source logic |
sensors/battery.h |
Add enum for capacity source |
fc/settings.yaml |
Add battery_capacity_source setting |
Summary
The DroneCAN
BatteryInfomessage contains comprehensive SOC data that INAV currently ignores. Implementing SOC support would allow smart batteries to report their actual state of charge instead of relying on current integration.Problem
Current implementation only extracts voltage and current:
Available DroneCAN BatteryInfo Fields
Solution
Add a new setting following the existing pattern:
New enum:
Implementation Approach
Hybrid (recommended):
Effort Estimate
3-5 hours
Files to Modify
sensors/battery_sensor_dronecan.csensors/battery_sensor_dronecan.hsensors/battery.csensors/battery.hfc/settings.yamlbattery_capacity_sourcesetting