feat(mavlink): Battery_Status_V2 MAVLink stream#25347
feat(mavlink): Battery_Status_V2 MAVLink stream#25347
Conversation
| configure_stream_local("BATTERY_STATUS", 0.5f); | ||
| configure_stream_local("BATTERY_STATUS_V2", 0.5f); |
There was a problem hiding this comment.
@MaEtUgR What's the normal way we handle the case where we are migrating between messages for the MAVLINK_MODE_NORMAL case (where it is OTA).
My guess is that we'd initially stream both like this, but we might also update QGC to request the message type it wants and set the other not to stream?
|
Did you test against QGC, and does QGC implement this?
FWIW We try match the most common definitions. I looked at all of them when we designed this message. One thing I would consider is modifying this more like https://mavlink.io/en/messages/common.html#FUEL_STATUS
In other words the recipient knows what is measured and what is inferred in all cases and can tell that it is working with a system that trusts the values it outputs. This is better than what the battery message does, which is assume the battery was initially full, and use the consumed charge or battery voltage to work out what was consumed - then estimate the remaining. Not sure we can though, because the approach comes from power modules, and I'm not sure we can "know" internally or from other sources what was calculated and what is measured. |
e62a823 to
f6f59f0
Compare
f6f59f0 to
f77786f
Compare
Tested, but Battery_Status_V2 is not implemented in QGC.
Changed the way of calculating capacity_remaining, now is based on remaining_capacity_wh/nominal_voltage. I'm not sure if this is the way which we should use, before was just remaining * capacity. |
Sorry, that was a side-note. This should match what it says on the mavlink spec, and we need to discuss with others if we want to modify the spec. I commented because the way that the fuel spec does it works well because you can measure fuel in different ways. It needs more thinking to make a change like this for batteries though, since so many things assume certain behaviour. Upshot, revert please if the change doesn't match the spec. |
I think after that change it's directly converts actual remaining energy to charge capacity using basic electrical relationship: https://www.inchcalculator.com/wh-to-ah-calculator/. The remaining * capacity approach would be more appropriate when only percentage-based remaining capacity is available. It's still according to mavlink spec. Of course we could add different behavior depends on MAV_BATTERY_STATUS_FLAGS_CAPACITY_RELATIVE_TO_FULL, but this flag is not available yet in the code. Next PR I will add BatteryContinous/Periodic/Cells. |
f77786f to
3d8f198
Compare
|
|
@Sayshara would you be able to continue on this PR? |
Yes, it's just waiting for review. |
3d8f198 to
9a8119f
Compare
463e7bd to
b6c1a98
Compare
|
This pull request has been automatically closed due to 120 days of inactivity. If you would like to continue, please feel free to reopen it or submit a new PR. |
|
Should we get this in? Is there handling in QGC? We don't want to publish both messages, so we'll need to find a good solution for the migration... I don't know how we do this while keeping backwards compat. |
@dakejahl We absolutely should get support for BATTERY_STATUS_V2. I believe that MAVSDK has support, but QGC does yet. This was pending review and an answer on https://github.com/PX4/PX4-Autopilot/pull/25347/changes#r2255643302 - which was exactly your question "how do we manage the transition". I don't know the "official patterns". My thinking is that QGC should request |
b6c1a98 to
657c4b6
Compare
|
FYI, I have updated this in line with my suggestion - removing streaming by default. I also fixed up an indexing error in the battery id. Claude seems to think this is good, and so do I by inspection. I have created mavlink/qgroundcontrol#14269 to request the new message if it is not detected, and display it. If you build this with Note though, that PX4 only sends BATTERY_INFO if a serial number is set, even if it is requested. So I can't test the full path with PX4 of a smart battery. |
2973364 to
f0fa905
Compare
|
@dakejahl @MaEtUgR Can you review this? I have looked at it, checked it with claude, and tested it via QGC in mavlink/qgroundcontrol#14269 - see #25347 (comment) above |
dakejahl
left a comment
There was a problem hiding this comment.
Not approving so @MaEtUgR can sign off, but nothing here looks merge-blocking. +1 on the stop-streaming-by-default migration via mavlink/qgroundcontrol#14269 — keeps the link budget sane and lets V2 land ahead of broad GCS support.
Three small inline nits on the V2 stream; all non-blocking.
| && !math::isZero(battery_status.voltage_v)) ? battery_status.voltage_v : float(NAN); | ||
| bat_msg.current = (battery_status.connected | ||
| && PX4_ISFINITE(battery_status.current_a) | ||
| && fabsf(battery_status.current_a - (-1.0f)) > FLT_EPSILON) ? battery_status.current_a : float(NAN); |
There was a problem hiding this comment.
Nit (same pattern on lines 82, 88): fabsf(x - (-1.0f)) > FLT_EPSILON is an unusual way to spell x != -1.0f for a deliberately set sentinel. FLT_EPSILON is ~1.19e-7, so this is effectively exact-equality — works, just reads strangely. x != -1.0f or x > -0.5f would be clearer.
| bat_msg.capacity_remaining = (battery_status.connected && PX4_ISFINITE(battery_status.remaining_capacity_wh) | ||
| && PX4_ISFINITE(battery_status.nominal_voltage) | ||
| && !math::isZero(battery_status.nominal_voltage)) ? | ||
| battery_status.remaining_capacity_wh / battery_status.nominal_voltage : float(NAN); |
There was a problem hiding this comment.
remaining_capacity_wh has no @invalid sentinel in BatteryStatus.msg (unlike voltage_v=0, current_a=-1), so a dumb power module that leaves it at 0 produces 0 Ah remaining instead of NaN. Same for nominal_voltage — the isZero guard protects against div-by-zero but not against "not measured." No regression vs. current behavior; worth revisiting when smart-battery fields get proper invalid sentinels, or by keying validity off source == SOURCE_EXTERNAL.
| status_flags |= MAV_BATTERY_STATUS_FLAGS_CHARGING; | ||
| } | ||
|
|
||
| if (faults & battery_status_s::FAULT_HARDWARE_FAILURE) { |
There was a problem hiding this comment.
Minor: FAULT_CELL_FAIL reasonably maps to MAV_BATTERY_STATUS_FLAGS_BAD_BATTERY — same "battery unusable" indicator you already set for FAULT_HARDWARE_FAILURE. One-line addition.
Solved Problem
Initial implementation for new mavlink message stream
BATTERY_STATUS_V2.It's base on BatteryStatus.msg, in a future we need to split this msg according to:
mavlink/rfcs#19
dronecan/DSDL#7
mavlink/mavlink#1846
Best to use similar structure to dsdl format of the battery messages (20004.BatteryInfoAux.uavcan, 20010.BatteryContinuous.uavcan, 20011.BatteryPeriodic.uavcan, 20012.BatteryCells.uavcan). Another question is why this is on ardupilot side, not common dsdl.
Solution
Changelog Entry
Alternatives
BATTERY_CELL_VOLTAGES.Test coverage
Context