Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RFC 0018 - Improved Battery Status Reporting #19

Open
wants to merge 56 commits into
base: master
Choose a base branch
from
Open
Changes from 44 commits
Commits
Show all changes
56 commits
Select commit Hold shift + click to select a range
f72ae85
RFC 0018 - BATTERY_STATUS v2
hamishwillee Mar 24, 2022
4a719f2
Update text/001x-battery_improvements.md
hamishwillee Mar 30, 2022
496d464
Remove energy_consumed - not required (developer feedback)
hamishwillee Mar 30, 2022
657d762
Remove type and function from v2 battery status
hamishwillee Mar 30, 2022
5c684c6
Remove question on removing the battery type/function (answered)
hamishwillee Mar 30, 2022
8247fbc
Update text/001x-battery_improvements.md
hamishwillee Mar 30, 2022
cdfcac1
Propose updated Battery cell voltage message
hamishwillee Mar 30, 2022
28b23db
Add charge state
hamishwillee Mar 30, 2022
f110cfa
Update text/001x-battery_improvements.md
hamishwillee Mar 30, 2022
3e56f60
Update text/001x-battery_improvements.md
hamishwillee Mar 30, 2022
f15e542
Update text/001x-battery_improvements.md
hamishwillee Mar 30, 2022
05be55e
Add note about duplication
hamishwillee Mar 30, 2022
cc94393
Add question about charge states into questions
hamishwillee Mar 30, 2022
9033cc9
Update 001x-battery_improvements.md
hamishwillee Mar 30, 2022
42cfe84
Update 001x-battery_improvements.md
hamishwillee Mar 30, 2022
dc63056
Propose removal of mode and charging state into fault
hamishwillee Mar 31, 2022
1a2fb83
percent_remaining is a uint8
hamishwillee Apr 6, 2022
8372532
Update text/001x-battery_improvements.md
hamishwillee Apr 6, 2022
57d9d9b
Remove time_remaining
hamishwillee Apr 6, 2022
bfa89c4
Add doc that percent_remaining is proposed as uint8
hamishwillee Apr 6, 2022
660d9c3
Update 001x-battery_improvements.md
hamishwillee Apr 7, 2022
2e63457
change `current` from a `int16_t` (cA) to a `int32_t`
hamishwillee Apr 7, 2022
199a2c6
Update 001x-battery_improvements.md
hamishwillee Apr 7, 2022
1295684
Make current_consumed a uint32
hamishwillee Apr 7, 2022
5e530eb
Clarify temp is "whole battery" not internal electronics
hamishwillee Apr 7, 2022
c8915b8
Add dronecan alignment as a key driver and link to the WIP discussion
hamishwillee Apr 14, 2022
9acf267
Update on handling power monitors
hamishwillee Apr 14, 2022
45c8361
Battery now has status flags
hamishwillee Apr 14, 2022
7f464ed
Missed a couple of faults. Added now
hamishwillee Apr 14, 2022
41a7fb8
Clarify current consumed is from vehicle being powered on
hamishwillee Apr 20, 2022
506de46
Update text/001x-battery_improvements.md
hamishwillee Apr 20, 2022
af11eaf
Update text/001x-battery_improvements.md
hamishwillee Apr 20, 2022
9d17b55
Remove cell fail fault - not needed according to jacob
hamishwillee Apr 20, 2022
abe7dce
Update text/001x-battery_improvements.md
hamishwillee Apr 20, 2022
469e5c3
Update text/001x-battery_improvements.md
hamishwillee Apr 20, 2022
ff245bb
add ids for messages close to smart battery info
hamishwillee Jun 1, 2022
e4e9b57
Add flag to indicate whether values are assumed to be re;ative full b…
hamishwillee Jun 2, 2022
8b9625f
Reserve final value of status flag for later extension
hamishwillee Jun 2, 2022
acc9e73
Update text/001x-battery_improvements.md
hamishwillee Jun 2, 2022
d563499
Update text/001x-battery_improvements.md
hamishwillee Jun 2, 2022
0f678c7
Update text/001x-battery_improvements.md
hamishwillee Jun 2, 2022
8801ef4
Battery might be OK to use during charging
hamishwillee Jun 2, 2022
e5aeab5
Update text/001x-battery_improvements.md
hamishwillee Jun 2, 2022
f84e83b
current to int32
hamishwillee Jun 2, 2022
5d19e49
Add the smart battery standard DS-013
hamishwillee Jun 2, 2022
75bdacc
Typo
hamishwillee Jun 2, 2022
5fb3ff8
MAV_BATTERY_STATUS_FLAGS_READY_TO_USE to MAV_BATTERY_STATUS_FLAGS_NOT…
hamishwillee Jun 3, 2022
ab3d25f
improve description not ready to fly
hamishwillee Jun 3, 2022
5fa4be2
Update text/001x-battery_improvements.md
hamishwillee Sep 21, 2022
6aa86db
Update text/001x-battery_improvements.md
hamishwillee Sep 21, 2022
ce99827
Update text/001x-battery_improvements.md
hamishwillee Sep 21, 2022
8e2deb7
Update text/001x-battery_improvements.md
hamishwillee Oct 12, 2022
b5f65c0
Update text/001x-battery_improvements.md
hamishwillee Oct 12, 2022
ea508a7
Update text/001x-battery_improvements.md
hamishwillee Oct 12, 2022
c25344b
Update text/001x-battery_improvements.md
hamishwillee Oct 13, 2022
12561b9
Update now that SMART_BATTERY_INFO was renamed to BATTERY_INFO
hamishwillee Feb 14, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
292 changes: 292 additions & 0 deletions text/001x-battery_improvements.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,292 @@
* Start date: 2022-03-26
* Contributors: Hamish Willee <[email protected]>, ...
* Related issues:
- [16-cell support #1747](https://github.com/mavlink/mavlink/pull/1747)
- [common: added voltage and current multipliers to BATTERY_STATUS #233](https://github.com/ArduPilot/mavlink/pull/233)
- [Add MAV_BATTERY_CHARGE_STATE_CHARGING #1068](https://github.com/mavlink/mavlink/pull/1068)
- dronecan / DSDL : [WIP smart battery messages](https://github.com/dronecan/DSDL/pull/7)

hamishwillee marked this conversation as resolved.
Show resolved Hide resolved
hamishwillee marked this conversation as resolved.
Show resolved Hide resolved

# Summary

This RFC proposes:
- a new `BATTERY_STATUS_V2` message that has a single cumulative voltage value rather than individual cell voltage arrays.
- a new (optional) `BATTERY_VOLTAGES` message that can be scaled to as many cells as needed, and which reports them as faults.


# Motivation

The motivation is to:
- reduce the memory required for battery reporting ([anecdotal evidence](https://github.com/ArduPilot/mavlink/pull/233#issuecomment-976197179) indicates cases with 15% of bandwidth on a default RF channel).
- Provide a cleaner message and design for both implementers and consumers.
- Align with DroneCan battery messages to ease transport and data conversion across different transports.

The [BATTERY_STATUS](https://mavlink.io/en/messages/common.html#BATTERY_STATUS) has two arrays that can be used to report individual cell voltages (up to 14), or a single cumulative voltage, and which cannot be truncated.
The vast majority of consumers are only interested in the total battery voltage, and either sum the battery cells or get the cumulative voltage.
By separating the cell voltage reporting into a separate message the new battery status can be much smaller, and the cell voltages need only be sent if the consumer is actually interested.

# Detailed Design

There are three parts to the design:
1. A more efficient status message
2. A scalable battery voltage message.
3. Mechanisms that allow the new messages to seamlessly coexist with the old one along with eventual deprecation of the older message.

## BATTERY_STATUS_V2

The proposed message is:

```xml
<message id="369" name="BATTERY_STATUS_V2">
<description>Battery dynamic information.
This should be streamed (nominally at 1Hz).
Static/invariant battery information is sent in SMART_BATTERY_INFO.
hamishwillee marked this conversation as resolved.
Show resolved Hide resolved
Note that smart batteries should set the MAV_BATTERY_STATUS_FLAGS_CAPACITY_RELATIVE_TO_FULL bit to indicate that supplied capacity values are relative to a battery that is known to be full.
Power monitors would not set this bit, indicating that capacity_consumed is relative to drone power-on, and that other values are estimated based on the assumption that the battery was full on power-on.
</description>
<field type="uint8_t" name="id" instance="true">Battery ID</field>
hamishwillee marked this conversation as resolved.
Show resolved Hide resolved

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
<field type="uint8_t" name="id" instance="true">Battery ID</field>
<field type="uint16_t" name="id" instance="true">Battery ID</field>

Is there a need to support more than 255 batteries? @AlexKlimaj thoughts? Would you ever go bigger than 255 in your box?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I hope not. That feels like excessive future proofing.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I mean .. maybe ... is it? What if someone wanted to replace autopilot with ardupilot? 🤨
https://www.google.com/search?q=how+many+batteries+in+a+tesla

see what I did there I rhymed

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dakejahl And you wonder why nobody likes you :-)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

haha ouch but you're wrong I am beloved. But no in DroneCAN I think it can make sense, probably not mavlink

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah yeah :-). I'm going to say no "right now". Yes this might come back and bite us, but it feels like a waste.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've thought about that one before too.....
But i guess one could create their own message at that point. :)

For mavlink no reason to waste space.

<field type="int16_t" name="temperature" units="cdegC" invalid="INT16_MAX">Temperature of the whole battery pack (not internal electronics). INT16_MAX field not provided.</field>
<field type="uint32_t" name="voltage" units="mV" invalid="UINT32_MAX">Battery voltage (total). UINT32_MAX: field not provided.</field>
<field type="int32_t" name="current" units="mA" invalid="INT32_MAX">Battery current (through all cells/loads). Positive value when discharging and negative if charging. INT32_MAX: field not provided.</field>
<field type="uint32_t" name="capacity_consumed" units="mAh" invalid="UINT32_MAX">Consumed charge. UINT32_MAX: field not provided. This is either the consumption since power-on or since the battery was full, depending on the value of MAV_BATTERY_STATUS_FLAGS_CAPACITY_RELATIVE_TO_FULL.</field>
hamishwillee marked this conversation as resolved.
Show resolved Hide resolved
<field type="uint32_t" name="capacity_remaining" units="mAh" invalid="UINT32_MAX">Remaining charge (until empty). UINT32_MAX: field not provided. Note: If MAV_BATTERY_STATUS_FLAGS_CAPACITY_RELATIVE_TO_FULL is unset, this value is based on the assumption the battery was full when the system was powered.</field>
hamishwillee marked this conversation as resolved.
Show resolved Hide resolved
<field type="uint8_t" name="percent_remaining" units="%" invalid="UINT8_MAX">Remaining battery energy. Values: [0-100], UINT8_MAX: field not provided.</field>
<field type="uint32_t" name="status_flags" display="bitmask" enum="MAV_BATTERY_STATUS_FLAGS">Fault, health, readiness, and other status indications.</field>
</message>
```

`MAV_BATTERY_STATUS_FLAGS` is a new enum that includes faults, charge state, and battery mode:
hamishwillee marked this conversation as resolved.
Show resolved Hide resolved

```xml
<enum name="MAV_BATTERY_STATUS_FLAGS" bitmask="true">
<description>Battery status flags for fault, health and state indication.</description>
<entry value="1" name="MAV_BATTERY_STATUS_FLAGS_READY_TO_USE">
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dakejahl I might be overthinking this, but should this perhaps be "not ready to use" ? i.e it we're constructing it from all the other faults so we're not saying it is ready to use, but that it is "not unready to use".

As it is now, you'd have to set the bit even if you didn't know the readiness, and by setting it you're saying its good to go. Whereas if we reverse it we're just saying - some flag that indicates there is a problem is set.

Anyway, not certain on this. I like a readiness flag too - just not sure we can be ready = not unready

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@hendjoshsr71 First, thanks for the review. Looks like a lot more issues than I first thought

This is supposed to reflect "there are no known issues that would prevent this flying" so how about MAV_BATTERY_STATUS_FLAGS_NOT_READY_TO_USE ?

The actual issues that set this would depend on the person setting up the system. If it is OK to charge in place, then this would not be a fault that set this.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dakejahl I might be overthinking this

I think you might 😆

Hmmm I'm not sure... You are saying you want it to be "not ready to use" since this would then correlate with a flag that gives us the reason for it being not ready? I would say you would infer this in the same way as seeing "ready to use" be set to zero. The other part is that an empty message (all zeroes) would be default to "not ready" which is a nice side effect.

Or maybe I don't see the point.

There is a question for you and @dakejahl on inverting the "ready to use flag" to "unready to use". The former is what users want, but the later is what we can realistically and reliably provide.

I don't understand how we can know it's "not ready" but can't know it's "ready"? They're the same thing just inverse.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dakejahl What we do is check a bunch of things which mean it is not ready to use. So what we are saying is there are no flags that indicate it is not ready to use. Then we're inverting that and saying, "if there are no flags that say it is not ready to use it is ready to use."

Are they semantically the same? Technically they are not, because we only detect "known issues". It could be that there is an unknown issue we do not know about - so we're telling people it is ready to use when it is not. A legal expert would care, but perhaps we do not need to.

The other part is that an empty message (all zeroes) would be default to "not ready" which is a nice side effect.

It means that if you don't have the ability to report or detect faults you have to set this as ready all the time.

That's kind of my point - you're not actually saying its ready, you're just saying you don't know of any faults.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ahh so you're saying "the system is not not ready" does not mean the same thing as "the system is ready"...? Essentially saying we could just not know the state. I honestly don't have a strong opinion on it, I think semantically you are correct but I sure do hate double negatives lol. So yeah we can change it to "not ready" and then the check would be if it's unset, easy enough. I'll leave that up to you.

<description>
The battery is ready to use (fly).
Set if the battery has no known issues that would make it unsafe to fly with. This includes critical faults, such as those that would set MAV_BATTERY_STATUS_FLAGS_REQUIRES_SERVICE or MAV_BATTERY_STATUS_FLAGS_BAD_BATTERY).
</description>
</entry>
<entry value="2" name="MAV_BATTERY_STATUS_FLAGS_CHARGING">
<description>
Battery is charging.
</description>
</entry>
<entry value="4" name="MAV_BATTERY_STATUS_FLAGS_CELL_BALANCING">
<description>
Battery is cell balancing (during charging).
Not ready to use (MAV_BATTERY_STATUS_FLAGS_READY_TO_USE would not be set).
</description>
</entry>
<entry value="8" name="MAV_BATTERY_STATUS_FLAGS_FAULT_CELL_IMBALANCE">
<description>
Battery cells are not balanced.
Not ready to use.
</description>
</entry>
<entry value="16" name="MAV_BATTERY_STATUS_FLAGS_AUTO_DISCHARGING">
<description>
Battery is auto discharging (towards storage level).
Not ready to use (MAV_BATTERY_STATUS_FLAGS_READY_TO_USE would not be set).
</description>
</entry>
<entry value="32" name="MAV_BATTERY_STATUS_FLAGS_REQUIRES_SERVICE">
<description>
Battery requires service (not safe to fly).
This is set at vendor discretion.
It is likely to be set for most faults, and may also be set according to a maintenance schedule (such as age, or number of recharge cycles, etc.).
</description>
</entry>
<entry value="64" name="MAV_BATTERY_STATUS_FLAGS_BAD_BATTERY">
<description>
Battery is faulty and cannot be repaired (not safe to fly).
This is set at vendor discretion.
The battery should be disposed of safely.
</description>
</entry>
<entry value="128" name="MAV_BATTERY_STATUS_FLAGS_PROTECTIONS_ENABLED">
hamishwillee marked this conversation as resolved.
Show resolved Hide resolved
<description>
Automatic battery protection monitoring is enabled.
When enabled, the system will monitor for certain kinds of faults, such as cells being over-voltage.
If a fault is triggered then and protections are enabled then a safety fault (MAV_BATTERY_STATUS_FLAGS_FAULT_PROTECTION_SYSTEM) will be set and power from the battery will be stopped.
Note that the associated fault (such as MAV_BATTERY_STATUS_FLAGS_FAULT_OVER_VOLT) should always be set whether or not the protection system is engaged.
hamishwillee marked this conversation as resolved.
Show resolved Hide resolved
</description>
hamishwillee marked this conversation as resolved.
Show resolved Hide resolved
</entry>
<entry value="256" name="MAV_BATTERY_STATUS_FLAGS_FAULT_PROTECTION_SYSTEM">
hamishwillee marked this conversation as resolved.
Show resolved Hide resolved
<description>
The battery fault protection system had detected a fault and cut all power from the battery.
This will only trigger if MAV_BATTERY_STATUS_FLAGS_PROTECTIONS_ENABLED is set.
Other faults like MAV_BATTERY_STATUS_FLAGS_FAULT_OVER_VOLT may also be set, indicating the cause of the protection fault.
</description>
</entry>
<entry value="512" name="MAV_BATTERY_STATUS_FLAGS_FAULT_OVER_VOLT">
<description>One or more cells are above their maximum voltage rating.</description>
</entry>
<entry value="1024" name="MAV_BATTERY_STATUS_FLAGS_FAULT_UNDER_VOLT">
<description>
One or more cells are below their minimum voltage rating.
A battery that had deep-discharged might be irrepairably damaged, and set both MAV_BATTERY_STATUS_FLAGS_FAULT_UNDER_VOLT and MAV_BATTERY_STATUS_FLAGS_BAD_BATTERY.
</description>
</entry>
<entry value="2048" name="MAV_BATTERY_STATUS_FLAGS_FAULT_OVER_TEMPERATURE">
<description>Over-temperature fault.</description>
</entry>
<entry value="4096" name="MAV_BATTERY_STATUS_FLAGS_FAULT_UNDER_TEMPERATURE">
<description>Under-temperature fault.</description>
</entry>
<entry value="8192" name="MAV_BATTERY_STATUS_FLAGS_FAULT_OVER_CURRENT">
<description>Over-current fault.</description>
</entry>
<entry value="16384" name="MAV_BATTERY_STATUS_FLAGS_FAULT_SHORT_CIRCUIT">
<description>
Short circuit event detected.
The battery may or may not be safe to use (check other flags).
</description>
</entry>
<entry value="32768" name="MAV_BATTERY_STATUS_FLAGS_FAULT_INCOMPATIBLE_VOLTAGE">
<description>Voltage not compatible with power rail voltage (batteries on same power rail should have similar voltage).</description>
</entry>
<entry value="65536" name="MAV_BATTERY_STATUS_FLAGS_FAULT_INCOMPATIBLE_FIRMWARE">
<description>Battery firmware is not compatible with current autopilot firmware.</description>
</entry>
<entry value="131072" name="MAV_BATTERY_STATUS_FLAGS_FAULT_INCOMPATIBLE_CELLS_CONFIGURATION">
<description>Battery is not compatible due to cell configuration (e.g. 5s1p when vehicle requires 6s).</description>
</entry>
<entry value="262144" name="MAV_BATTERY_STATUS_FLAGS_CAPACITY_RELATIVE_TO_FULL">
<description>
Battery capacity values are relative to a known-full battery.
If set: the supplied capacity_consumed and capacity_remaining are relative to battery full.
If unset: capacity_consumed is relative to drone power-on, and capacity_remaining estimated from capacity_consumed and the assumption that the battery was full at power on.
This bit should be set by smart batteries and unset for power modules.
If unset a GCS is recommended to advise that users fully charge the battery on power on.
hamishwillee marked this conversation as resolved.
Show resolved Hide resolved
hamishwillee marked this conversation as resolved.
Show resolved Hide resolved
</description>
</entry>
<entry value="4,294,967,295" name="MAV_BATTERY_STATUS_FLAGS_EXTENDED">
hamishwillee marked this conversation as resolved.
Show resolved Hide resolved
<description>Reserved (not used). If set, this will indicate that an additional status field exists for higher status values.</description>
</entry>
</enum>
```

The message is heavily based on [BATTERY_STATUS](https://mavlink.io/en/messages/common.html#BATTERY_STATUS) but:
- removes the cell voltage arrays: `voltages` and `voltages_ext`
- adds `voltage`, the total cell voltage. This is a uint32_t to allow batteries with more than 65V.
- `current_consumed` has changed to capacity_consumed, and from an `int32_t` to a `uint32_t`.
This future proofs from 32767 mAh limit to 4294967295 mAh
- removes `energy_consumed`, which essentially duplicates `capacity_consumed` for most purposes, and `capacity_consumed` in mAh is nearly ubiquitous.
- adds `capacity_remaining`(mAh).
- This allows a GCS to more accurately determine available current and remaining time than inferring from the `capacity_consumed` and `percent_remaining`.
- This will be reliable for smart batteries.
- A flag has been added to indicate whether this is calculated from an assumed or known-full battery.
A GCS can use this to prompt that batteries be fully charged for power modules.
- Note that with capacity consumed and remaining, you have the full capacity and you could calculate the percentage remaining.
However percentage remaining is supplied anyway, as the other values are optional, and this is actually the one value that most users really want.
- change `current` from a `int16_t` (cA) to a `int32_t` (mA). Maximum size was previously 327.67A, which is not large enough to be future proof. New value gives up to 2,147,483A. The value is positive when discharging, and negative when charging.
hamishwillee marked this conversation as resolved.
Show resolved Hide resolved
- removes `time_remaining`.
```xml
<field type="uint32_t" name="time_remaining" units="s" invalid="UINT32_MAX">Remaining battery time (estimated), UINT32_MAX: Remaining battery time estimate not provided.</field>
```
- This is an estimated "convenience" value which can be calculated as well or better by a GCS, in particular on multi-battery systems (from original charge, `capacity_consumed` and looking at the rate of `current` over some time period).
- Better to be lightweight.
- `percent_remaining` changed from int8 to uint8 (and max value set to invalid value).
This is consistent with other MAVLink percentage fields.
- removes `battery_function` and `type` (chemistry) as these are present in `SMART_BATTERY_INFO` and invariant.
hamishwillee marked this conversation as resolved.
Show resolved Hide resolved
```xml
<field type="uint8_t" name="battery_function" enum="MAV_BATTERY_FUNCTION">Function of the battery</field>
<field type="uint8_t" name="type" enum="MAV_BATTERY_TYPE">Type (chemistry) of the battery</field>
```
- A GCS that needs invariant information should read `SMART_BATTERY_INFO` on startup
- A vehicle that allows battery swapping must stream `SMART_BATTERY_INFO` (at low rate) to ensure that battery changes are notifie (and ideally also emit it on battery change).
hamishwillee marked this conversation as resolved.
Show resolved Hide resolved
- New `battery_status` (`MAV_BATTERY_STATUS_FLAGS`) replaces [`fault_bitmask`](https://mavlink.io/en/messages/common.html#MAV_BATTERY_FAULT), [`charge_state`](https://mavlink.io/en/messages/common.html#MAV_BATTERY_CHARGE_STATE) and [`mode`](https://mavlink.io/en/messages/common.html#MAV_BATTERY_MODE)
```xml
<field type="uint8_t" name="charge_state" enum="MAV_BATTERY_CHARGE_STATE">State for extent of discharge, provided by autopilot for warning or external reactions</field>
<field type="uint8_t" name="mode" enum="MAV_BATTERY_MODE">Battery mode. Default (0) is that battery mode reporting is not supported or battery is in normal-use mode.</field>
<field type="uint32_t" name="fault_bitmask" display="bitmask" enum="MAV_BATTERY_FAULT">Fault/health/ready-to-use indications.</field>
```
- The state is almost all inferred from the battery remaining. Traditionally the GCS sets appropriate levels for warning - the battery has a less accurate view on appropriate warning levels for a particular system, making this redundant. The exception is charging status.
- The mode and fault are reasonable, but make more sense as general status indication.
- The status loses some faults which make no sense (e.g. `MAV_BATTERY_FAULT_SPIKES`) or which can now be inferred (like deep discharge).


#### Questions

- Do we need all the other fields?
- Are there any other fields missing?
- Should we have `MAV_BATTERY_FAULT` for critical level "just before deep discharge"? The battery can know this, and it might prevent over discharge.
```xml
<entry value="1024" name="BATTERY_FAULT_CRITICAL_LEVEL">
<description>Battery is at critically low level. Undamaged, but not ready to use.</description>
</entry>
```
- `MAV_BATTERY_STATUS_FLAGS`
- Should this include `MAV_BATTERY_STATUS_FLAGS_IN_USE` (connected, drawing significant power to fly). Not clear when you would need this or how you would use it. Or precisely what would count as "in use".

## Battery Cell Voltages

The proposed battery message is:

```xml
<message id="371" name="BATTERY_CELL_VOLTAGES">
<description>Battery cell voltages.
This message is provided primarily for cell fault debugging.
For batteries with more than 12 cells the message should be sent multiple times, iterating the index value.
hamishwillee marked this conversation as resolved.
Show resolved Hide resolved
It should be streamed at very low rate (less than once a minute) or streamed only on request.</description>
<field type="uint8_t" name="id" instance="true">Battery ID</field>
<field type="uint8_t" name="index">Cell index (0 by default). This can be iterated for batteries with more than 12 cells.</field>
<field type="uint16_t[12]" name="voltages" units="mV" invalid="[0]">Battery voltage of 12 cells at current index. Cells above the valid cell count for this battery should be set to 0.</field>
</message>
hamishwillee marked this conversation as resolved.
Show resolved Hide resolved
```

Cell voltages can be used to verify that poorly performing batteries have failing cells, and to providing early warning of longer term battery degradation.
It is useful to have long term trace information in logs, but not necessary for this to be at particularly high rate.
Therefore the message provides all information about the battery voltages, but is expected to be sent at low rate, or on request.

As designed, the message will not be zero-byte truncated (field re-ordering means that the array is last).
The message might be modified to make:
- `voltages` an extension field. For a 4S battery this would save 12 bytes per message but lose checking. If we do this we might as well mandate "no extension".
- `id` and `index` into `uint16_t`. For a 4S battery this would save 10 bytes per message,and retain mavlink checking on field. It would cost 2 additional bytes on every new message.


#### Alternatives

An alternative is just to send fault information.
This assumes that the smart battery is capable of providing the long term trend analysis that can be obtained from logs using the above message.

```xml
<message id="???" name="BATTERY_CELL_VOLTAGES">
<description>Battery cell fault information.</description>
<field type="uint8_t" name="id" instance="true">Battery ID</field>
<field type="uint8_t" name="index">Cell index (0 by default). This is iterated for every 64 cells, allowing very large cell fault information. </field>
<field type="uint64_t" name="fault_mask">Fault/health indications.</field>
</message>
```

## SMART_BATTERY_INFO

[SMART_BATTERY_INFO](https://mavlink.io/en/messages/common.html#SMART_BATTERY_INFO) is already deployed and it is not clear if it can be modified. It may be possible to extend.

Add note that it must be streamed at a low rate in order to allow detection of battery change, and should also be sent when the battery changes.

Questions:
- What low rate is OK for streaming? is there another alternative for tracking battery change

hamishwillee marked this conversation as resolved.
Show resolved Hide resolved


## Migration/Discovery

`BATTERY_STATUS` consumes significant bandwidth: sending `BATTERY_STATUS_V2` at the same time would just increase the problem.

The proposal here is that GCS should support both messages for the forseeable future.
Flight stacks should manage their own migration after relevant ground stations have been updated.


# Alternatives

TBD

# Unresolved Questions

TBD

# References

* ?