APM Code questions

What are the units of the “_voltage” variable in the AP_BattMonitor.cpp library ?
Whole volts? millivolts? Something else?

Also, can I use the function “capacity_remainng_pct()” as a comparison variable? In other words, would the code
if ((capacity_remaining_pct()) < another_variable) {


And does the “capacity_remaining_pct()” function return 80 for 80% or 0.80 for 80%

Look at the function definition here https://github.com/ArduPilot/ardupilot/blob/0cee2f28963de6091197fe2bf9974a32f97cb2d3/libraries/AP_BattMonitor/AP_BattMonitor_Backend.h

/// capacity_remaining_pct - returns the % battery capacity remaining (0 ~ 100)
uint8_t capacity_remaining_pct() const;

if(uint8_t < another_var)
should work.

Thanks for answering.
I’m stuck with 3.2.1 because I have been unable to compile PixHawk code despite trying multiple times…

The reason for my question is that I have noticed three weaknesses in the APM 3.2.1 FW:

It will ARM when the voltage is below the battery failsafe value. I’m using a 4 Cell battery and the failsafe battery voltage is set to 13V, yet it will arm when the battery voltage is 12.2V.

If the user flies for awhile, disconnects the battery and later reconnect it to fly again, the percentage left resets to 100%, even though the battery is now half empty. This might be OK when flying around the park and the 'copter can make it back to launch, but it isn’t good when flying a longer mission.

I have had a case where a battery suddenly lost a lot of capacity - it was rated at 10,000 mAH, but actually held about half that. The 'copter was on a long mission when I noticed that even though the calculated remaining was 40%, the battery voltage was 12V and falling fast… It did not make it “home” because it was too far away.

I want to add a battery “health” term to the failsafe, so that if the battery voltage is below 13.6V and the remaining percentage is above 80% a FAILSAFE is triggered. Likewise, I want to trigger failsafes if the battery voltage is below 13.2 and the remaining percentage is > 60 and also if the battery voltage is below 12.8 and the percentage is > 40.

Finally, I want to prevent arming when a battery failsafe has been issued.

The addition of these extra conditions should prevent a launch with a partially depleted battery, and should bring the craft home early if a degraded battery is used.

I added a variable “_batt_numcells” that defaults to 4.

In my added code below, I thought that returning a “TRUE” would trigger failsafe and also prevent the craft from arming, but it does not. What am I doing wrong? The following is taken from my modified AP_BattMonitor library.

// check capacity if current monitoring is enabled
if((_monitoring == AP_BATT_MONITOR_VOLTAGE_AND_CURRENT) && (min_capacity_mah > 0) &&
(_pack_capacity - _current_total_mah < min_capacity_mah)) {
return true;

// check battery health - Added by Clinquist

if ((_voltage < (_batt_numcells * 3.4f)) && (capacity_remaining_pct() > 80)) {
      return true;

if ((_voltage < (_batt_numcells * 3.3f)) && (capacity_remaining_pct() > 60)) {
      return true;

 if ((_voltage < (_batt_numcells * 3.2f)) && (capacity_remaining_pct() > 40)) {
      return true;

// end check battery health

Wouldn’t it make sense to ad a parameter generally which prevents from arming when voltage is below a given limit?
One could add it to pre arming check.

Say you can’t arm if battery is below 80% and FS will be triggered at a given voltage if the copter is in the air.

My scheme automatically takes care of that. When you first power the craft, the battery percentage will be 100%. If the battery voltage is below 13.6V a failsafe will be issued and the craft wouldn’t arm.

Of course, I could make that 13.6V any value I choose.

For me it would make sense to have 2 values.
14.8V is 100%
13,6V is xx% -> FS -> RTL
So I can arm with 13,7V but that doesn’t make sense for me.
If I want to start a mission it should be say 14.6V or 80% at least.

I hope one can understand what I mean. :wink:

Why recompile ? just install 3.5.4

3.5.4 won’t run in APM boards - only PixHawks. As I stated in my
earlier msg, I have been able to compile ver 3.2.1 for APM, but I can’t
compile PixHawk code - even though I have tried.

I have 8 quads or ‘hexes’ running on APM2.8 boards, and I don’t want to

I know what you mean. I can make the percentage any value I choose. I run 4 Cells, so FS = 16.8V.

If the craft has been “unplugged” from the battery and you plug it in, the battery percentage in the controller is reset to 100%. My logs show that by the time I have 80% left, my battery voltage is about 15.5V. I can put in a little "safety margin: and make that 15.2V. So if I change the code to require the battery to be above 15.2V if the percentage is above 80%, then the craft won’t arm.

I want to prevent the condition where the battery is partially discharged when plugged into the 'copter - which will then say the percentage is 100%. If no one checks the battery voltage, it would be possible to send the craft on a long mission - and it would not be able to return.

On the other hand, if you fly, disarm, and re-arm WITHOUT disconnecting the battery, the battery percentage is remembered. Mission Planner shows the correct percentage and all is well.

Also, I had a situation where a battery was defective. It had a full charge (16.8V) and MP reported 100% battery left.
I sent it on a medium-length mission. It was out of (control) radio range when I noticed that the battery voltage was 12.2V, but the percentage left was over 40%. The low voltage triggered the battery failsafe, but the craft didn’t make it home. If the system had noticed that the percentage left was 80%, but the voltage was only 14V (or so) it would have triggered a failsafe and returned home while it still had enough power to get home.

That is what I’m trying to accomplish.

Well, looks like you have limited options here, but it might help if you backported this PR to 3.2.1:

Take a look at it. It might get you on the right direction