Skip to content

Feature: Add DroneCAN Battery SOC support #3

@daijoubu

Description

@daijoubu

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions