Battery Selection Revisited

battery
A typical lead acid battery. It’s 12V, 80Ah. Or is it?

Batteries are often advertised with a nominal voltage and nominal charge. It’s tempting to take those numbers at face value and assume that regardless of operating circumstances, a battery will sit at its nominal voltage and run until its nominal charge has been depleted. Reality is more complicated than that.

Christopher Milner reminded me of this in a brief conversation this week. He is using 13 3.2V, 100Ah LiFePo4 batteries in series to power the deck motor on his mowing rig. Stringing them together in series gets you close to 48V in their charged state. He reports getting about 3 hours of runtime while powering a motor that consumes 1300W.

This surprises me because my own calculations suggested four 12V, 35Ah lead acid batteries should be sufficient. Christopher obviously knows what he is doing and I trust his experimental results much more than I do my own back of the envelope calculations. The discrepancy means I need to reevaluate my numbers.

When making my calculations I did not take battery discharge rates into account. This is a big mistake, as I’ll show below. But first, for my own educational benefit, I’d like to introduce you to the C-rate, a way to quantify how fast you pull current out of a battery.

The C-Rate

What is a battery’s C-rate? Our good friends at Wikipedia define it as:

The C-rate is defined as the charge or discharge current divided by the battery’s capacity to store an electrical charge.

In layman’s terms, the C-rate is just the ratio of an arbitrary discharge rate to the battery’s charge capacity. It’s a simple way to describe how much current you’re demanding from a battery relative to the battery’s total stored charge. If you’ve got a battery rated for 10Ah and you discharge it at 5A, the C-rate would be:

Untitled
The C-rate if you were to discharge a 10Ah battery at 5A.

It’s kind of a janky way of defining things in my opinion. A is really an inverse hour, or stated differently, the unit of measure for a C-rate is h−1. Also, don’t confuse the C-rate with Coulombs, the unit of measure for charge. Clear as mud?

The reason I write all of this is so we’re all on the same page about what a C-rate is. If I’m wrong, please comment below, because I am going to proceed with this understanding of the C-rate going forward.

The C-rate is a useful measure because the total amount of charge you can extract from a battery depends on how fast you take it out. If you try to pull 100A out of a 10Ah battery, you’re not going to get nearly as much charge out of the battery as you would if you discharged it at 1A.

Additionally, when you demand a large amount of current from a battery, your voltage starts dropping fast. This is important because electrical power, which is ultimately what we’re after, is voltage times current. If your voltage drops you get less power, even if you’re withdrawing the same amount of current from the battery.

Your batteries are going to be much happier and live much longer if you stick with a reasonable C-rate. Having said all of that, how do the four 12V, 35Ah batteries I selected stack up against the expected current draw they’ll experience?

Our SLA Batteries Reevaluated

Previously I estimated the total current consumption of our robot at 197A. I think this is a conservative number, but I’m going to roll with it anyway. The number reflects current consumed by the three deck motors, two drive motors, and various electronics at their worst case scenarios.

I’m using two sets of two 12V, 35Ah batteries wired in parallel, then in series to get an equivalent battery that’s 24V, 70Ah. The discharge rate for one battery in this configuration is half the total current consumption because we have two sets of two batteries wired in parallel. This means that one battery is discharged at a rate of 98.5A.

The datasheet for one of these batteries shows the following chart, with various C-rates:

SP12-35 Discharge Characteristics
Run times and terminal voltages for our 12V, 35Ah SLA battery at various discharge rates.

At a discharge rate of 98.5A, our C-rate is 2.81C. Looking at the chart above, that would mean our batteries will last for ~8 minutes. Yikes. And realistically, the 2.81C curve may extend to about 8 minutes, but the voltage drops off so fast after about 4 minutes that you’ll probably start noticing performance problems very quickly.

Also interesting to note from the chart above is that the one hour discharge rate is in fact not 35A as you’d expect with a 35Ah battery. It’s actually 0.628 times 35Ah, or 21.98Ah. To truly extract the 35Ah charge from the battery, you can only discharge it at a C-rate of 0.05C, or 1.75A.

Having written all of this, I wonder to myself why manufacturers don’t just list curves with specific discharge rates in Amps. The chart above would be completely unambiguous if they just showed a curve for 105A, 70A, 35A, 21.98A, etc. The conversion is tedious and honestly, if you don’t truly understand C-rates you leave with the impression that these SLA batteries are much more capable than they truly are.

Looks like we will need to use some lithium batteries after all. Thanks for saving me $400 on some batteries that wouldn’t have worked Christopher!

Is a Compass Even Necessary?

bad compass health
My favorite Mission Planner error message: Bad Compass Health.

The compass drives two very costly design constraints into the robot lawn mower:

  1. The need to minimize the number and size of steel or ferrous parts in the design.
  2. The need to separate the compass from the motors to prevent electro-magnetic interference.

To address the first constraint, I selected a 5000 or 6000 series aluminum for the robot chassis and deck. That is quite costly both from a material standpoint and from a fabrication standpoint. And ultimately, you’re going to have some amount of steel in your robot. You can’t avoid it.

The second constraint requires the compass to be raised above the motors to a level high enough to get it out of the magnetic field created by the motors. Because I’ve placed the flight controller and other electronics in the same control box with the compass, several wires have to be run between this box and the power box. Shielding those wires is going to be tricky. Long story short, it creates lots of secondary design inefficiencies.

Reading through the forums and in my own research, I’ve come across a few interesting anecdotes:

  1. Kenny Trussell reports that when steel mower blades begin to spin at high RPMs, the compass heading begins to drift by some amount, about 20º.
  2. Christopher Milner had to place a 4ft tall mast on his vehicle to sufficiently separate his compass from the noise created by two drive motors and one brushless DC motor.
  3. Unplugging and disabling all compasses on my wheelchair robot doesn’t cause any EKF errors, and after traveling a few feet in the wrong direction, the robot corrects its heading somehow, without the compass. I suspect the wheel encoders aid this process.

In light of this information, I am beginning to question whether I even need a compass. It seems to be creating more problems that it solves. The bad compass health error messages in Mission Planner are starting to get very annoying, even though they don’t usually seem to impact the robot wheelchair’s ability to navigate properly.

According to U-Blox, you can use two ZED-F9P modules configured as a moving base-rover combination to calculate the vehicle’s heading. Even with a spread between the antennas of 10in, U-Blox says the heading accuracy is 0.8º. Some folks on the Ardupilot forum are starting to investigate using the modules in this way, and I suspect it will be a much more accurate way to obtain the vehicle’s heading.

I’ve had enough bad luck with compasses that I’m willing to get rid of them altogether and use the ZED-F9Ps for heading exclusively. This allows some significant improvements to the robot design. I guess I’ll head back to the drawing board for the time being…

A Poor Man’s RTK Base Station

enclosure-closeup.png
I may not be able to afford a Emlid Reach RS2, but I’ve got a cordless drill and an Amazon Prime account, dang it!

Putting my RTK base station on the mailbox works pretty good, but it takes a while to set it up and it’s not very robust. Using it in this manner results in a few problems:

  1. The cell phone battery pack that I use to power to the receiver turns off after a while. I’m not sure if this is because the receiver only draws ~120mA of current and it doesn’t detect the receiver, or if it just times out. Either way, it’s quite annoying to discover the reason I can’t get an RTK fix or float is because the base station isn’t even on.
  2. The neighbors getting their mail usually block enough satellite signals to cause the receiver to lose an RTK fix. Cars driving down the street will often affect the quality of reception, too. Unfortunately, I can’t pick up the mailbox and move it to a more favorable location.
  3. The receiver and antenna are exposed to the elements. While I usually use them in good weather, I would like to be able to use them without having to worry about risking damage to the units from rain, wind, and the Kansas critters.
  4. When I’m out testing in the parking lot there’s not an equivalent of my mailbox out there for me to set the receiver on. The roof of my car doesn’t count because it’s not geostationary. I’d like to have a way to repeatably locate the receiver when I’m testing in the parking lot.
  5. Maybe I’m paranoid, but I’m always worried about some punk kid walking off with the base station module when it’s not within my line of sight. The punk kid I used to be in my teenage years would have done something malicious like that. It’d be great if I could make it a little bit more difficult to steal.

With these goals in mind, I decided it was time to build a real base station. One like the Emlid Reach RS2, but doesn’t cost me $1,899.

A Glorified Enclosure

The Emlid guys are geniuses. They basically took an RTK GNSS chip they can buy in bulk for $150 a piece, slapped it in a super nice thermoplastic case, developed an app that is more or less equivalent to U-Blox’s U-Center, and then stuck a price tag of $1,899 on it. I’m embarrassed I didn’t think of doing it myself.

They do offer some nice benefits with that $1,899 price tag, such as integral Wi-Fi and data logging capability, but in my humble opinion, those features aren’t worth what they’re charging. Realistically, I need a tripod, a mostly waterproof enclosure, a lead acid battery with a charger, and a cover for my GNSS antenna. Something like this:

RSTP-A10001 (06-21-19)
My version of the Emlid Reach RS2.

I have a 12V lead acid battery and charger I stole from an old weed eater that I intend to use for this enclosure. The battery is rated for 3.6Ah, and according to the Ardusimple website, the board consumes 600mW at 5V, so 120mA of current. That would mean you could keep the Ardusimple board on for 30 hours. Not too shabby! I don’t know if they’re including the radio current consumption in those numbers, but even if it’s twice the 600mW they listed, we should be in good shape.

I’m still learning how to use these GPS modules, so I want to have access to the micro USB port that lets me communicate with them via U-Center. I found one of these cables for that purpose. I want to be able to interface with the board without opening the enclosure.

The guys that designed the Ardusimple boards were very forward thinking, and they made them such that you can power the board from any port or all the ports. The board has two micro USB ports, one for GPS data and the other for debugging the XBee radios. I don’t anticipate needing to use the XBee port often, so I am going to power the board with it instead.

To step down the 12V to 5V the board needs, I am going to use one of these DC to DC buck converters. Instead of two wire leads for the 5V output, it has a micro USB connector. Very handy. This converter should plug and play right into the XBee micro USB port.

One concern I have with it is RF interference. I’ve read some comments saying these converters don’t play well with FM radios. The way my enclosure is designed, I’ve got it sitting right below the Ardusimple board. GPS signals are in the 1.5GHz range if I remember right, so maybe we’ll be okay.

I’d like to use a tripod that’s stouter than your consumer grade camera tripod. Ideally it would have a hook under the center that I can hang a plumb bob from to make sure I’m setting the tripod up in the same location every time. I found a tripod that appears to fit the bill on Amazon.

tripod stud
A survey grade tripod that looks promising. The 5/8-11 UNC stud is stout, but a little inconvenient.

Most survey grade tripods appear to have a 5/8-11 UNC threaded stud, so I’ve used a low profile cap screw with a coupling hex nut to mount the enclosure on the tripod.

The tripod mount method
The coupling nut used to interface the enclosure with the tripod.

Last but not least, I need a way to protect the antenna as it sits on top of the enclosure. I opted for the OEM antennas that Ardusimple sells for the simple reason that all the other antennas they offered came with no less than 5m of extra cable. Yikes. Where would you put all of that cable? The OEM antenna cable was 30cm long.

The downside to the OEM antenna is that it doesn’t have any protective case. I could have 3D printed something, but I like to keep things simple. I really just need a dome looking thingy to cover it.

It’s kind of amazing what Google can find if you type “plastic dome” into the search field. At least for me, it turned up this on the first page of results. Pretty much exactly what I’m looking for. I intend to use a modified pipe gasket and some rubber washers for an approximately water tight seal.

The dome is about an eighth of an inch thick, so to make sure it doesn’t attenuate the GPS signals too much, I did a little test where I put a similar plastic bowl over the receiver. It affects the signal strength only marginally.

Last but not least, every GPS antenna needs a good ground plane. Sparkfun sells a 4in diameter ground plane for $5. It’s 0.125in thick steel which is a bummer for drilling holes through, but it beats routing the circular profile out of a piece of bar stock.

bom
Bill of material for the poor man’s RTK GPS base station. The items I have on hand have a zero quantity.

Total cost? Should be under $200, depending on shipping for all these items. You too can have a Emlid Reach RS2 for the low, low price of $200.

Field Testing and RTK GPS Stuff

I have decided that I need to refine the wheelchair robot’s ability to navigate accurately and robustly before I shell out a few thousand dollars to build the robot lawn mower. The goal here is to have the wheelchair robot “mow” my lawn before I invest in the actual robot lawn mower. If the wheelchair robot can’t do it, the robot lawn mower doesn’t have much of a chance, either.

So I’ve spent most of my time testing the wheelchair robot and the RTK GPS system. I have been typically placing the base on my community mailbox because it is geostationary, has a large metallic surface to prevent multipath, and a decent view of the sky.

IMG_5373
The base station, located on top of my community mailbox. The green disk is the antenna. Neighbors give me funny looks when they go to get their mail.

Surprisingly, I was able to get several RTK Fixes partially underneath my large maple tree in my front lawn. While in RTK Fixed mode I had the rover running a mission with 10 waypoints in a 3m diameter circle. I cranked down the waypoint radius to 0.3m to try and make sure the robot was accurately traveling to each waypoint.

rtk map
The circular mission in my front lawn. The satellite imagery is from winter time. GPS in blue is the U-Blox Neo-M8N, GPS2 in green is the U-Blox Zed-F9P, and POS in red is the calculated position by the EKF.

The map above shows some calculated positions prior to obtaining the RTK fix and after the RTK fix is lost.

IMG_5372
The view from the ground. The mailbox in the picture is where I have the base station sitting.

There is some offset between the satellite imagery and the actual location on the ground, which makes things a little confusing, especially when planning a mission close to many obstacles. I almost ran into my neighbor’s basketball goal after I lost my RTK fix.

To give you a better idea of the quality of the fix, here is the latitude reported by the GPS receivers and the blended location as calculated by the EKF:

rtk fixed graph
The latitude reported by the U-Blox Neo-M8N, U-Blox Zed-F9P, and the EKF position estimate in blue, green, and red, respectively.

The RTK fix in the graph above is first obtained at 18:06:15 and is maintained intermittently until about 18:14:12. The reported HDOP for both GPS receivers was close to 0.7, but despite this, I am impressed that by default, the EKF is giving much more weight to the RTK solution. You can see this in the graph: the red and green lines are much closer than the blue line.

The oscillations in the graph above are from the circular mission I was running. It looks like I had a pretty good RTK fix from about 6:09PM to about 6:13PM. This was about 11 laps about the circle.

Some additional information about the fix status:

rtk status
The fix status across time. 6 is an RTK Fix, 5 is RTK Float.
gps status
How much time was spent in each fix status.

I don’t want to oversell these results, because they weren’t typical of the entire afternoon. I spent a good chunk of time running the wheelchair robot in Acro mode tuning the throttle and steering parameters, and I wasn’t able to get an RTK fix throughout that time. It’s very much a patience thing.

It’s the Wires, Dummy

After doing some reading this week, I discovered a few additional ways to check if the encoders are working properly:

  1. Use the Analog Input pins on the Arduino to see what voltage the encoder outputs on high and low signals. It will give an idea of what the voltage is across a range of rotation speeds.
  2. Use a potentiometer as a pullup or pulldown resistor to bring the high signal higher or the low signal lower if they end up not being high enough. This lets you determine a good resistance value to use.

Checking the encoder signal voltage with the Arduino revealed that the low signal was 0.00V, and the high signal was in the neighborhood of 4.38 to 4.71V depending on the speed the encoder rotates at. I would expect this out of two $60 encoders, and it’s in line with the datasheet, although a little lower than the advertised 4.5V. So I don’t see any need to use pullup resistors to differentiate between the high and low outputs.

So taking a step back, the encoder symptoms are:

  1. When both left and right wheels rotate in the same direction at a static speed of ~90RPM, the rpm1 and rpm2 values in Mission Planner randomly oscillate between positive and negative numbers, but roughly equal in magnitude.
  2. Rotating one wheel by itself causes both rpm1 and rpm2 values to oscillate around zero RPM.
  3. Both encoders function normally when plugged into the Arduino.

Come to think about it, if the A and B signals are cross wired, that would cause the behavior described above. You’d be sending the A signal from two separate encoders into the A and B inputs on the Pixhawk, which would explain the random positive and negative switches, and the otherwise random magnitude RPM values I was seeing. Quadrature encoders work by measuring a predictable state change in the A and B channels, and cross wiring the A signal output on encoder 1 with the B signal input would cause chaos.

But I always wire everything right the first time, so it can’t be that. No sir. Gotta be some really obscure with the hardware issue, or a problem with the Ardupilot code. Sarcasm, in case that wasn’t apparent.

Well after checking both of those issues, it turns out there was a wiring issue. I had the encoders wired through the power enclosure and then up into the control enclosure through the DB15 cable into the Pixhawk. Lots of places that wiring can be done incorrectly. And I had the A wire on encoder 1 cross wired into the B input for encoder 2. I need to start taking my own advice about troubleshooting.

After swapping wires, things worked wonderfully. In fact, after doing some brief autonomous testing in my backyard I decided to take the wheelchair robot up to the parking lot for some more thorough testing. I’ll have a writeup on that soon.

Encoder Math

I was able to test the wheel encoders on the wheelchair robot the other night. I had mixed success. The rpm1 and rpm2 status values in mission planner were all over the place. But they were consistently the same magnitude positive or negative:

RPM1 and RPM2
Reported RPM values for the left and right motors.

So something is not right. Talking with the folks on the Ardupilot forum it sounds like I selected an encoder that has too much resolution for the speeds I’m running the motors at.

So to make sure I’ve selected the correct encoders (or to determine which encoders I should have selected) I need to do some math. The encoder I purchased is an E5-900-394-NE-S-H-T-3. It’s rated for 900 counts per revolution of the encoder (CPR).

Maximum Encoder RPM

Encoders have a maximum speed at which they can spin and still accurately measure angular rotation. Per page 4 of the E5 datasheet, an E5 encoder rated for 900CPR can spin at a maximum speed of 20,000RPM.

The encoder is attached to the motor armature shaft, which is in turn connected to a 32:1 gear box. So based on this maximum encoder speed and gear ratio, the fastest corresponding tire rotation speed is:

max tire speed
The maximum rotation speed of the tire on the gear motor for a given maximum encoder rotation speed.

Connected to a small 12V battery, the tire rotation speed was about 60RPM. Doubling that on the wheel chair robot (it has a 24V power supply) is still well below this maximum speed.

So I am confident the encoder can report rotation measurements accurately. Now whether or not the Pixhawk can read them at the speed it reports them is another story altogether…

Frequency of Pulses

How fast is the encoder sending pulses? Let’s say that the tire on the gear motor rotates at 150RPM. Because it’s a quadrature encoder, you get four pulses for every count. The frequency of pulses is then:

pulses at 150rpm
The number of pulses in one second if the tire on the gear motor rotates at 150RPM.

That’s a lot. It’s one every 3.47 microseconds. Can the Pixhawk handle that? I’m not sure.

Resolution

What distance does the robot travel per encoder count? The diameter of the tire is 10in:

travel per count
The distance the tire travels after one encoder count.

That’s a ton of resolution. Way more than we realistically need. Something in the neighborhood of 0.03in/count is more reasonable.

Pull Up Resistor

Another tip I got from the Ardupilot forum was to use two 10kΩ pull up resistors between the A and B signal pins and the Vcc pin on the encoder. I tried that last night without much success. I also tried to pull the A and B signal pins down to ground, but that didn’t work either. I tried it on the left encoder but not the right to see what the difference would be. The numbers were still all over the place, but they were now slightly different. So there’s that.

Going Forward

I am going to purchase an encoder with 32CPR, which results in 1024 counts per tire revolution, and a resolution of 0.031in/count. Hopefully this will be compatible with the Pixhawk. If the 32CPR encoder still doesn’t work, at least I’ll know the issue is something else.

Correction: The Magic Number is Exactly 32

Because the ratio I measured a few days ago was a strange non-integer ratio, I decided to open up the gearbox and count teeth. It was frustratingly messy, to say the least.

IMG_4381
Inside the wheelchair motor gear box. Lots of grease! This was after I had taken out about 80% of all the grease.

I was hoping to be able to count the number of teeth on each gear without taking the whole thing apart, but this proved quite difficult. There’s not really a good way to mark a tooth when the whole thing is swimming in grease.

After a while, I decided to sit down and do some math. It was a flashback to my old engineering school days. I was able to count the teeth on some of the gears (with a fair degree of confidence) and using this information, the problem statement became:

A gearbox has a gear ratio of 31.8. There are four gears in the box. The output gear has 32 teeth. The gear connected to the output gear has 11 teeth. A second gear with an unknown amount of teeth is rigidly attached to the same shaft as the gear with 11 teeth. This gear is then driven by a worm gear connected to the motor. How many teeth are on the second gear?

With most word problems, I find myself drawing pictures to make things more clear. I made a simple CAD model of this setup to try and get a better grip on how the gears worked together.

gear model
A simple model of the gears in the gear box. The left gear has the output shaft with the tire on it, and the lower right cylinder represents the worm gear attached to the motor.

Assign a letter to each gear in the system. The gear on the output shaft is A, the gear meshing with it is B, the gear on the same shaft is C, and the worm gear in the lower right is D.

The total ratio is the ratio between A and B times the ratio between B and C times C. Remember, one revolution of a worm gear will advance the corresponding spur gear one tooth, or 1 divided by the number of teeth on the gear. Putting it all together:

Untitled
The composite gear ratio for the wheelchair gearbox.

Wait a minute… that’s just a fancy way of saying the gear ratio is A, or the number of teeth on the output shaft gear. That can’t be right. Or can it?

Remember we measured the gear ratio at 31.8. I did some more estimating and came up with a number closer to 31.9 by counting more tire revolutions (320, or so I thought), but because I can’t exactly line the tire up in the same spot it started from, there was always going to be a little error in the calculation.

And come to think of it, the more tire rotations I counted, the closer my estimation came to 32 exactly. To come up with the 31.8 number I counted 159 revolutions. I was off by one tire rotation. And to come up with the 31.93 number I counted 639 rotations, which meant I was off by about 1.25 tire rotations. Turns out I’m not very good at counting.

At this point you might be wondering why I didn’t use the other encoder to measure the gear ratio with much higher precision (and without all the mess). The output shaft on the gearbox is 17mm diameter, but I mistakenly thought it was 8.5mm. I misread the radius measure in my CAD program and thought it was a diameter measure instead. You can jury rig a 10m ID encoder to fit on an 8.5mm shaft, but not a 17mm shaft. 

Long story short, I like to do things the hard way, and the magic number is actually 32. Exactly 32.