I’ve learned a lot about the behavior of DC motors from the book Introduction to Mechatronic Design. Much of what I will discuss in this post comes from chapter 20 of this book. Electrical engineers reading this post will laugh at how elementary some of this information is, but it was news to me as a mechanical engineer.
I find that I solidify my understanding of ideas and concepts by writing about them. So what follows is a brief book report on a phenomena often called inductive kickback, which I believe was the cause of the wiring failure on my robot.
A motor is an inductor. Inductors store energy in magnetic fields. When you apply voltage to a motor, a magnetic field is created around the motor. A unique characteristic of inductors is that they resist changes in the flow of electricity through them.
If you were to suddenly disconnect the voltage source, the magnetic field would try to keep electricity flowing through the motor. But because there is no where for that electricity to go, the voltage across the motor terminals increases instead. And it can increase to very high levels, sometimes thousands of volts.
The energy stored in the motor’s magnetic field has to go somewhere. What usually happens is the voltage becomes high enough across the motor terminals that a nearby component becomes a target for electricity to arc through and flow out of the motor.
I didn’t state it in my previous post, but to power on the deck motors I’m using a large relay. To turn them off you have to open the relay, and you end up creating exactly the inductive kickback situation described above. And with nowhere for electricity to flow, I think the voltage between some of my wires became so large that it arced through the insulation.
The damaged wires in the picture above are the + voltage wire on the motors and a battery ground wire, curiously enough. And notice how close they are to each other: a perfect place for electricity to arc. Better than the contacts inside the relay, which was still functional, surprisingly.
I now know why wires are voltage rated: it has nothing to do with the conductor material or size, and everything to do with the insulation. The insulation will only prevent arcing below a certain voltage threshold. And in the field several weeks ago, it looks like I greatly exceeded that threshold, whatever it was for those wires.
I checked the Posi-Lock website, and their connectors are rated for 600V. I don’t remember where I got my wire from. I’m sure it was the cheapest knock-off stuff I could find. The insulation has no identifying marks, so I’m not sure it’s voltage rated at all.
Next post I’ll describe the changes I’m going to make to robustify the wiring and electrical components in the robot mower.
If you look closely at the charts in the previous post, you’ll notice they end quite abruptly. The picture above shows why.
I have the robot mower configured so the blades only turn on when you hold the rudder stick to the right. The stick is spring loaded, so letting go of it returns it to center, deactivating the blades.
The field I was testing in had several large shrubs in it. One of my goals in the field was to push the envelope on what the mower was capable of cutting through, so I let it mow over several of them in autonomous mode. However, there was a particularly large shrub in the robot’s path, and so I decided to turn the mower blades off by releasing the rudder stick.
As expected, the blades stopped. But the robot stopped moving, too. This was curious: the robot should have continued driving. So I pressed the emergency stop button on the robot to immobilize it, and walked over to the truck where I had Mission Planner running on my laptop.
The Mission Planner screen was frozen as if it wasn’t receiving telemetry from the robot. It took me a few minutes to realize that the issue wasn’t Mission Planner or my laptop radio: it was that the robot wasn’t sending telemetry. And even more curiously, the voltage reading on my SLA batteries said 12.50V. I was worried that I’d really fried my batteries, so I walked back over to the robot to investigate.
Opening the battery bay I found a slight amount of smoke and that awful burnt plastic smell from melted wire insulation. But other than that everything seemed fine. There wasn’t a smoldering fire inside the robot. The batteries weren’t hot to the touch.
At first I chalked it up to too much current running through the wires. The robot uses 120A at peak current, and at those levels even a small amount of resistance could cause the wires to heat up a lot. Perhaps the wires just got hot enough to melt the insulation and came into contact right at the moment I decided to shut the mower blades off?
This just so story didn’t sit well with me. What an awful coincidence that the wires failed at exactly the same moment I was shutting off the motors, especially after the robot ran fine for five minutes prior. Why didn’t they fail earlier?
Additionally, why didn’t the exposed wire conductors fuse together after they came into contact? I’ve heard of people using SLA batteries smaller than mine to spot weld 18650 battery tabs together. The wires were really close together, but weren’t touching when I opened the battery bay. And the wire strands don’t seem to be melted judging from the picture above. Which was extraordinarily lucky, given how bad that could have been.
I did have enough sense to put a 100A fuse on my batteries. It seemed logical that the fuse was what saved my bacon. But using the multimeter to test the fuse revealed that it was not, in fact, blown. At this point I was completely bewildered. I thanked the good Lord that the robot hadn’t turned into a massive lead acid fireball, made sure all my batteries were all disconnected, packed up, and went home.
I’m sure readers are ready to scold me for all of the janky things going on in my battery bay, and I certainly deserve that criticism. My mantra is make it robust, and I definitely did not live up to that standard with my wiring. Below is a full picture of the battery bay.
I have my own list of janky things in here that I intend to fix. What do you see that is janky? Feel free to comment below!
In the next post, I’ll explain what I think went wrong, and the improvements I’m going to make to mitigate the problem and eliminate all the redneck wiring I’ve got going on.
I didn’t spend much time in the field testing the robot mower, but the little time I did spend gave me a treasure trove of information about how the robot mower performs. Below are some high-level measures.
I set the robot cruise speed to 1m/s or 2.2mph. I’ve run the robot mower faster in manual mode, but for obvious safety reasons, a moderate walking pace seemed best. If the robot gets out of control, I want to be able to catch it.
I am using a Mauch PL-200-HV current sensor on the robot. The sensor is connected to the positive terminal on my batteries, so it reports the total current used by robot: sensors, drive wheels, mower deck motors, etc. Once the mower is spooled up, current consumption levels out at about 90A.
The first portion of the graph above is the robot mower operating autonomously without the deck motors turned on. The huge spike is when the deck motors get turned on. It’s curious it says the peak is 196A: the PL-200-HV is only rated for 200A. I wonder if the spike was actually larger than shown, but due to its current rating, the sensor only reported ~200A.
There is a surprising variability to the amount of current used by the deck motors. In the garage, the deck motors would use 46A +/-1A. It was kind of impressive how steady current consumption was. But throw some grass under the robot and you get a ton more variability. Current consumption for the whole robot varies from 65A to 120A with the deck motors on.
Grass is typically pretty homogenous, even out in the field, so this was unexpected. I went and reviewed the logs from my backyard, and they look about the same. Even controlling for pivot turns at the end of a pass, the current consumption is all over the place.
It does appear to dip a little with each turn, but only ~15A. Maybe I’m reading into it too much. There were some small shrubs and some pretty gnarly crab grass plants out in the field. The current variation might just be the mower running over those things.
I also wanted to see how much the battery voltage dropped when running the deck motors in a real-world situation.
I made sure all four of my batteries were individually fully charged before going to the field. But any way you cut it, asking 90A out of four 35Ah SLA batteries is pushing it. With the deck motors on, the nominal battery voltage drops to 20V.
To get the total power consumed by the robot you need two things: current consumed and the voltage level when it was consumed. Mission Planner will do the math for you by multiplying the current and voltage at each time step and then adding them up for a total energy consumed graph.
Unfortunately, Mission Planner won’t differentiate that graph for you so you can see what the power consumption was at any given time. But if we assume the power consumption is linear over the five minute time interval above, we can estimate it.
This number is encouraging. I’ve seen the drive motors on typical electric riding mowers consume more than 1kW by themselves, excluding the deck motors. I need to do some more testing to see how efficient the robot mower is on less flat terrain. But as you’d expect, there appear to be a lot of power savings to be had by getting rid of the guy riding the mower.
Regarding the blade motor rotation speed, there are two ways I can think of to estimate this. One way is based on the current consumed by each motor. Take that number to the motor performance charts and you can estimate rotation speed.
The other is to see at what frequencies the mower is vibrating at. Thanks to some new developments by the Ardupilot folks, this is a pretty straightforward task. If you can find the frequency where you get strong vibrations at, you can assume that’s the probably speed at which the motors are rotating.
The mower uses about 5A when running without the blade motors on. That means all three motors consume 85A, or each motor consumes 28A.
At 28A of current consumption, an E30-400 motor spins at 5100RPM, uses 540W of power and and achieves 1N·m or 0.74ft·lb torque. One of the big question marks in the robot mower design has been how well the motors would perform. It appears they’re just about perfect, operating right at the peak of its efficiency curve.
Speaking of efficiency, one thing I did notice about the deck motors was that even after a few minutes of operation, they were very hot to the touch. So hot I couldn’t keep my hand in contact without significant discomfort. Yes, I did try. I’m guessing they were north of 140°F.
Even if the motors are 79% efficient, that means that 21% of that 540W, or 113W, gets turned into waste heat. That’s a fair amount of heat to dissipate through a 5in long, 3in diameter cylinder by free convection. It might be worthwhile to come up with some kind of cooling fin to attach to the motor housing.
Ardupilot now has a feature that lets you analyze logs to see where vibration issues might exist. It looks at data recorded by your IMU and does a fast Fourier transform on the data to find frequencies at which you have high levels of vibration.
Using this method to estimate the motor rotation speed gives you several graphs that look like the one below.
My understanding is that this graph gives you the strength of vibration at certain frequencies. I am unsure of the units on the Y axis. I think they’re m/s, but that seems awfully high. But then again, the mower deck is basically a giant vibratory table. I have no reason to believe they’re not accurate.
One thing that is interesting to note is that the amplitude of vibration is high in the X and Y directions across the spectrum, but less so in the Z direction. I think X is the forward to aft direction and Y is the left to right direction on the robot. So high levels of vibration along those axes makes sense when you think about a giant unbalanced motor rotating along an axis perpendicular to those two directions.
I’m assuming that all three motors are spinning at close to the same speed, but in reality, I’m sure they’re all off by some amount. I’m not sure how that affects the accuracy of this method of estimating the mower blade speed. Regardless, 4680RPM jives with the estimates obtained from the motor chart. The truth is probably somewhere in the middle, perhaps 4800RPM.
15000ft/min is well below the 18000ft/min limit that manufacturers abide by. But judging from the good cut quality in the field, it might be possible run the motors slower. This would reduce the power we need to run the robot. AmpFlow makes a motor that is identical to the E30-400 that is a little bit shorter and uses less power. I might see if it would make sense to use this motor instead.
I made some setting changes to the RTK GNSS modules based on some great comments I received a few posts back. I outlined those changes in this post. After that post, I made one additional change to the CFG-NAVSPG-DYNMODEL configuration item. I set it to 3 = Pedestrian.
The graph above shows the RTK fix status. The changes I made in that post resulted in a rock solid RTK fix. The little dips in RTK status were less than a second in duration. Thank you to Sean Smith and Frank Beesly for their valuable feedback!
The magnetometer performance was more or less garbage. I think a good portion of my cross track error is due to the compass variance corrupting an otherwise good position solution given by my wheel encoders and RTK GNSS.
Reviewing the telemetry logs, before I was even in autonomous mode, the EKF was reporting a marginal compass health reading. And the chart below tells you all you need to know about the rest of the compass performance.
The reported magnetic field strength jumps by 0.15 Gauss after you turn the deck motors on. It might be possible to zero this out in the software by finding the offsets when the deck motors are on, but I have so little confidence in the magnetometer at this point, it’s not worth the effort in my opinion. RTK GNSS yaw seems like a much more robust solution for heading.
Keen observers will notice something peculiar at the 17:16 mark on these graphs. More on that in the next post.
The past few Saturdays I’ve been playing with the robot mower in my backyard. It’s been fun manually driving it around my sprinkler well, flower beds, and garden. The fun ends a lot faster than I’d like: my push mower is 21in wide, but the robot mower is 36in wide, so it doesn’t take very many passes to get most of it mowed.
I’ve spent a lot of time in the backyard for two main reasons: firstly, I want to make sure the mower is safe before I take it somewhere it could hurt a bystander. And secondly, I want to make sure it doesn’t do an embarrassingly bad job at cutting grass.
Before I even took the mower out into the backyard, I ran it in my garage with the door down for a good hour or so to make sure the blades were installed securely. The first time I spooled it up was pretty scary. The garage is a giant echo chamber, and so it sounded a lot louder than when I had it running in the backyard.
Once I was satisfied it wasn’t going to vibrate apart, I maneuvered it into my backyard to see how it handled in manual mode, and how good of a job it did cutting my grass. Overall, it performed very well, making grass clippings without any difficulty. I did, however run into two issues:
In manual mode, you can take turns pretty quickly, resulting in some large side forces on the turnbuckle eyes. These turnbuckles were only rated for 36lbf in tension and I wondered how well they’d hold up. Guess we know the answer to that question.
While taking one of those fast turns in manual mode, I had a tire pop off. Yikes! Upon closer inspection, it turns out the nylon portion of the locknuts on the motor shaft were not actually threaded onto the shaft.
In my CAD model I had 1.5 threads engaged. Not great, but enough engagement to where I wasn’t worried about it. In reality, I didn’t get them threaded on all the way. I replaced both locknuts with a split lock washer and a jam nut.
These were good issues to discover in the backyard, where I could easily fix them without much embarrassment.
Satisfied that everything was working well, I loaded up and headed out to the field to try an autonomous mission. My backyard is great for manual mode, but it’s too small to run an autonomous mission.
It’s always good to have goals when you head to the field. For this field trip, I wanted to accomplish the following:
Practice getting the mower from my garage to the field. With four 35Ah lead acid batteries in the mower, it weighs close to 300lb now. Getting it from point A to point B is turning out to be an art in and of itself.
I made some changes to the ZED-F9P RTK GNSS settings based on comments made on a prior post. I wanted to determine if these changes helped or hurt my ability to maintain an RTK fix.
Being in a field with tall grass, I also wanted to push the envelope and see what the mower could cut effectively. The homogeneous fescue in my yard isn’t that difficult to cut.
Collect some general data about the mower’s performance. How much power does it actually use? How hot do the motors get after running for a while? How well does it mow autonomously?
Before I was using the mower deck, I only had two batteries in the battery bay. Loading and unloading isn’t too bad in this scenario: you can pretty easily drive the mower up the ramps and into the bed of my truck. With the other two batteries installed, that process becomes a little sketchier.
The wheel chair gearmotors have a neat little quarter-turn mechanism that disengages the output shaft from the rest of the gear train and lets the wheels spin freely, so I used this feature to push the mower up the ramps and into the bed of my truck. It’s too difficult to precisely maneuver the mower up the ramps and into the bed using the RC transmitter with the added battery weight.
Once in the field, I drove the mower out a safe distance away from the street to let it start working on an RTK fix. I wasn’t worried about absolute position, so I had the RTK base station configured to survey-in its location and used whatever it eventually settled on.
After I had an RTK fix, it was off to the races. I made a mission that was approximately a 100ft square and planned passes that were spaced 30in apart.
I configured channel 4 on my transmitter, the rudder stick, to control the power to my mower blades. This way it functioned as a dead man switch: if I let go of it, it would spring back to the neutral position. I designed relays inside the power enclosure to engage when the stick was held to the left. To keep the mower blades on, the stick must remain in that position.
After the mower made a few passes autonomously, I turned the blades on. That’s what you see in the video at the top of this post.
If the mower had maintained its position perfectly during the mission, each pass should have overlapped 6in because the mower deck is 36in wide and each pass was spaced 30in apart. Unfortunately, the mower’s position floated around by a fair amount. The un-mowed portions of the field are a result of this position error, which I’ve heard referred to as cross track error.
In some areas, the width of un-mowed grass was as large as 16in. This was a little disappointing. On average it was closer to about 8in. I need to find ways to improve the mower’s position estimate, so I don’t have to tighten up the spacing between passes.
The robot was using the magnetometer for heading, and you can see in the video that after each 180° pivot turn, the mower weaves a little bit as it tries to figure out its heading again. I intend to run another mission in the field soon with the magnetometers disabled to see if this improves the heading. Long term, I will look into using an additional RTK GNSS receiver to estimate the robot’s yaw.
This post is already pretty long, so I’ll make a separate one to review the logs and performance metrics I wanted to measure out in the field.
While designing the robot mower, I spent a lot of time working on the chassis, electronics enclosures, and wire routes. I tried hard to select components I could easily acquire at a reasonable cost, and that effort paid big dividends when I went to get everything built.
Unfortunately, I didn’t spend nearly as much effort on how the mower blades would attach to my motors, or even what the mower blades would look like. I assumed I could easily find any mower blade size I would need, or that making my own custom blades wouldn’t be difficult.
Now that the blades are the only thing missing on the robot mower, I’m realizing how mistaken that assumption is. I designed the mower deck for three 12in long blades, thinking that surely such a size exists. But most blades are generally in the neighborhood of 20in long.
Small gasoline powered mower engines operate at speeds in the range of 2,500RPM to 3,000RPM, and to achieve an appropriate blade tip speed slightly less than 19,000ft/min, the math forces you to use a blade that is between 19in to 22in long. Blade sizes outside this range aren’t common.
Initially I decided this wasn’t an issue: I’ll just make my own blade. It’s just bar stock with two sharp edges, right? Well, kind of. There’s a fair amount of metallurgical considerations that go into mower blade fabrication. On the one hand, you want a soft, ductile blade that doesn’t shatter when it hits a rock or tree stump. But on the other, you want the blade to be able to keep a sharp edge for a long time, which means making the blade, at least near the sharp edge, more brittle.
Cutting grass creates an inherently moist environment under the deck, so mower blades are usually painted or feature some kind of corrosion resistance. And on top of all this, a good blade will have a small bend opposite the cutting edge to create a little wing so that the grass clippings can be pulled upward resulting in a nice, even height cut.
The more you learn about mower blades the more you start to realize that buying one is really the way to go. In your research you’ll come across horror stories of guys who made their own mower blades and either welded them poorly or jury rigged them to work and then got hurt or even killed by the shrapnel from a blade shattering. Just this video alone should give you pause: there’s a lot of energy under a mower deck.
So off I went to find a 12in long mower blade. The closest I could find was one that was 12.125in long, which leaves 0.375in between the blade tips when they rotate past each other instead of the 0.625in I had designed for. We’re about to find out how accurately the mower deck weldment was made. I really hope I don’t have to grind the ends of the blades down because they crash into each other.
Finding a blade is only half the battle. How do you attach it to the 0.5in diameter keyed shaft on the E30-400 motor? The crankshaft on most push mowers I’ve seen has a threaded hole in the shaft for bolting the blade on. The E30-400 has nothing of the sort.
Could you drill and tap a hole in the end of the shaft? Possibly. But a #10-24 threaded hole is about the biggest you could drill and tap, and that only gives you 0.083in of edge margin from the major diameter of the threads to the keyed portion of the shaft. Too close for comfort in my mind.
The first solution that I came up with was to take a piece of 1.5in long, 2in diameter round stock, bore a 0.5in hole in it, key the hole, and then drill and tap holes for mounting the blade and some set screw holes to clamp the key up against the shaft. But in this scenario, the set screws are the only thing that holds the blade on the shaft. Better than nothing, but not by much.
I got a few quotes on three of these parts and the keyway really kills you on cost. I got several no bids because of the keyway alone. And the quotes I did get back were pretty high. Because I don’t like spending $300 on blade adapters, it was back to the drawing board.
What I really need is something with a keyway already in it. Initially I looked into some keyed pulley bushings, but they too have no way to hold themselves on the shaft. That and they have to match your hole pattern on the blade, and none of them met that criteria. They’re cheap, which is nice, but don’t really work for this purpose.
Eventually I got turned onto the idea of using solid shaft couplings. They’re keyed and include set screws. But the outer diameter for most half inch couplings is 1.5in or larger. That leaves no clearance for the bolts to mount the mower blade, which are 1.625in apart.
After some more digging, I found these smaller OD shaft couplings. And on top of their 1in outer diameter, they come with 2 pairs of set screws offset by 90°. Not bad! Take one of them and weld it to a plate with a hole pattern matching your mower blade, and you’ve got a custom mower blade adapter for ~$30 a piece after material and labor. The result looks like this:
The nice thing about the plate is that you can get a lock nut on the back side. I’m less worried about things vibrating loose compared to the machined adapter where the bolts run straight into a threaded hole.
But even with four set screws clamping up against the shaft, you really need some positive retaining feature to make sure the blade stays on the shaft. To meet this design objective, I figured it’s best to keep things simple: drill a small hole perpendicular to the coupling and the motor shaft, and then run a small hairpin through it. You don’t need a big one to keep it on the shaft.
The hairpin will add a little bit of eccentricity, as will the set screws. How much? I guess we’ll find out soon. Once the parts get back from the shop I’ll post some graphs and pictures.
Several comments on my post about the RTK GNSS results I experienced in the parking lot have made me reconsider how good my RTK fix really was. I was able to get a fix pretty easily, but it was fragile, and would frequently drop back to float without any apparent change in the environment.
When searching for ways to improve the robustness of the RTK fix, I came across this very comprehensive discussion about u-Blox receiver settings. The consensus I gathered from the discussion was that there are two configuration changes on the ZED-F9P boards that can really improve your RTK fix robustness: tightening up the elevation mask and increasing the signal to noise threshold.
To change these settings, I connected the ZED-F9P module via USB to my computer and then connected to it within the u-Center software. I then went to View > Generation 9 Configuration View. I double clicked on the Advanced Configuration on the left pane to show all the various configuration items.
You can use the CFG-NAVSPG-INFIL_MINELEV configuration item to set the elevation mask. This angle is measured from the horizon upwards. Satellites below this elevation are excluded from the navigation solution. The default is 10°, which I changed to 15°.
You can use the CFG-NAVSPG-INFIL_MINCNO configuration item to set the signal to noise ratio. The default is 6dbHz. I set mine to 35dbHz.
It was kind of a pain to remove the module from the robot, connect it to my laptop, change the settings, and then replace it in the robot, so I didn’t do any A-B testing on these values, although I may in the future. The 15° elevation mask and 35dbHz signal to noise values were recommended from the discussion linked to above.
I did do an A-B test on an aluminum foil ground plane to see how that would improve the fix quality.
Below is the results with and without the ground plane. Initially I had the robot parked in my driveway under some trees, but after waiting more than 10 minutes for an RTK fix, I decided to drive the robot out in the street where there was a better view of the sky. Shortly thereafter, I got a fix.
But with the foil ground plane, I was actually able to get a fix in my driveway under the trees. I drove the robot along my street at about 2:30 to see how robust the fix was. Much fewer hiccups, even with a more challenging environment.
I ran the same mission down my street and back with and without the foil ground plane. The ability to keep the RTK fix with the foil was quite surprising. It’s definitely an improvement.
I will take these settings and foil ground plane to the parking lot soon and see how they perform.
When I mow my lawn, I spend five minutes putting on mowing clothes and walking out to the garage to grab the mower, and this experience has influenced the productivity solution I think the lawn care industry needs. The pain I experience involves pushing the mower. Lawn care companies, on the other hand, experience pain in a whole host of other areas. The two situations are worlds apart, and the comments on my last post made that crystal clear. Thank you to those who shared their thoughts!
As I think about these ideas, I’m starting to realize the problem I’m solving really isn’t the right one. The tag line on this blog is “a project devoted to an autonomous lawn mower.” But the real goal is actually increasing lawn care productivity. An autonomous mower is only a means to accomplish that goal.
Greenzie and Mowbotix haven’t succeeded yet because they haven’t built a system that increases lawn care productivity. While they have successfully removed the operator from the mower, they’re making a mistake by trying to sell it to lawn care companies. Integrating an autonomous lawn mower with the way lawn care companies operate today actually makes them less efficient.
Lawn care companies are just as much about logistics as they are about mowing grass. Successful lawn care companies are able to quickly ferry workers and mowers to multiple job sites throughout the day. But to do this they use expensive tools: a truck and a trailer. And beyond the cost of the truck and trailer, they also waste a lot of time travelling between job sites.
These are major costs that get baked into the price people pay for mowing services. Which is great: it means that there is a lot of waste in the way lawns are currently mowed, and that it’s possible that a new way of mowing lawns can exploit these inefficiencies for profit.
I like searching the internet for other people who are making autonomous lawn mowers. You can learn a lot by seeing how others are approaching the problem. Over the years, I’ve found several folks who’ve made great progress. Yet everywhere I look I still see people on riding mowers cutting their grass the same old-fashioned way. What gives?
When I started the mower project, the problem I was solving seemed blindingly obvious. Mowing is unpleasant to do personally and expensive to hire out. Let’s build a machine that mows a lawn without a human. It will sell itself!
Both Greenzie and Mowbotix did just that. They built machines that can mow huge fields with great precision. Why haven’t they conquered the lawn care industry with their cutting-edge technology? The answer, in my humble opinion, has nothing to do with the maturity or sophistication of their technology. It has everything to do with productivity.
If you think back to economics 101, you’ll recall that productivity is the amount of output you get for a given input. For an autonomous lawn mower to be successful in the marketplace, it has to not only remove the operator from the machine but increase productivity while doing so.
And therein lies the problem. To illustrate, imagine a fictitious Joe’s Lawn Care company, who is using standard lawn care technology available today. A typical day for Joe would go something like this:
Joe drives to the job site he needs to mow.
He unloads his mower, hops on, and starts cutting grass.
When he’s finished, he loads the mower back on the trailer and drives to the next job site.
He repeats steps 1 through 3 until he’s finished with the day’s work.
If Joe were to upgrade to an autonomous lawn mower, his day would look like this:
Joe drives to the job site he needs to mow.
He unloads his mower, opens his laptop, loads a mission, and starts cutting grass.
When he’s finished, he loads the mower back on the trailer and drives to the next job site.
He repeats steps 1 through 3 until he’s finished with the day’s work.
How much does an autonomous lawn mower improve Joe’s productivity? The answer: none. And that’s being generous.
Joe gets paid to be out there monitoring the autonomous lawn mower, even if he’s sitting in the truck sipping iced tea while it cuts the grass. He still needs to transport the mower to the job site, unload, and load it. In this light, an autonomous lawn mower doesn’t reduce Joe’s labor costs at all. In fact, it probably increases them because the setup time at each job site will be longer than the time it takes to hop on a riding mower.
And on top of that, an autonomous lawn mower will likely cost much more than a typical riding mower. To give you an idea of how much, I’ll direct you here and here. Essentially, Greenzie and Mowbotix are asking you to bring them your existing mower, $5,000, and they’ll retrofit it for autonomy.
The worst part? To use their solution, you need to pay a significant monthly fee. Wasn’t the whole point of this exercise to get rid of the monthly fee, i.e. the wages you pay the guy to run mower? Talk about back to square one. If that’s how we’re going to market the solution I understand why autonomous lawn mowers haven’t caught on yet.
Framing this information in productivity terms, the inputs for an autonomous mower solution:
Cost thousands of dollars more than an ordinary riding mower.
Still require a worker to setup, monitor, and load up when finished.
Require a significant monthly fee to operate.
On the output side, you get to use your same riding mower at the same speed to cut the same amount of grass as before. And that assumes it doesn’t take longer to get the autonomous mower up and running once you’re at the job site.
I’m going to be honest, this has been a tough post to write because the solution I’m working on suffers from many of these same issues. I don’t intend to disparage Greenzie or Mowbotix: both of them have way cooler robots that are much more robustly autonomous than mine.
But as they exist today, these autonomous mowing solutions, mine included, cost more than traditional lawn mowing technology and result in about the same level of output. We’ve been solving the wrong problem, or a very small part of a much bigger problem.
Removing the operator from the machine is a step in the right direction, but to truly increase lawn care productivity it’s going to take more than a mower that can drive itself. I will be doing some pondering on that over the next few days.
It doesn’t matter how fast you move if it’s in a worthless direction. Picking the right thing to work on is the most important element of productivity and usually almost ignored. So think about it more!
Previously I was using GPS blending between a u-Blox NEO-M8N and a ZED-F9P. When the F9P had an RTK fix solution, all was well. But after losing the RTK fix, the position estimate reverted to the inferior M8N position solution.
So I conducted a few experiments to see if there was a way to get a better position estimate. I realized while tweaking parameters that the final position estimate is what we’re really trying to improve, not just the quality of our RTK fix from the F9P module. A better RTK fix will help our position estimate, but that’s only part of the equation.
Instead of feeding arbitrary coordinates into the base F9P module, this time I let it survey in with a precision of 2.5m and a time of 300s. I was surprised how close to the map imagery the survey in solution was. It was off by ~18in would be my guess.
I started by unplugging the M8N module, but unfortunately the compass is also powered by the 5V and GND pins on the data cable. So with both modules active, I set the GPS_AUTO_SWITCH parameter to 3, so that only the second GPS, the F9P, would be used.
This was a great way to test things because the flight controller was still logging the M8N data, but it wasn’t used for computing the robot’s position.
I was skeptical that this change would actually improve things because the F9P maintains an RTK fix only intermittently at best. But the results surprised me.
The Ardupilot software has some magic in it (meaning code I don’t currently understand) that allows the rover to continue with high accuracy even without a GPS solution at times. I think the wheel encoders are helping significantly in this regard but I can’t say for certain.
And related, the blue line is the M8N position accuracy. It’s really terrible. At times it’s a parking stall width, about 2m, from the RTK fix position. In hindsight, I was corrupting a really good position solution by blending it with a solution that was always off by at least 2m.
I looped the same square mission about 20 times and placed screwdrivers on the asphalt at the center of the robot’s travel to mark it’s path and check its repeatability. I would estimate the path drifted ~4in over the 20 loops.
Here’s a picture of the first few loops of the mission. Even with some hiccups in the RTK fix solution, the overall position estimate is very good.
I didn’t realize it until I started reviewing the logs, but the cell phone battery pack that I was using to power the base F9P module went to sleep after about 10 loops. That means no RTCM stream from the base, which means no RTK fix at the rover. But even without an RTK fix for 10 loops, the position solution was still very good.
In hindsight, the repeatability could be even better than ~4in that I was seeing if we could have intermittently re-established an RTK fix during that time.
Moral of the story: don’t ruin a really good answer (RTK fix) by averaging it with a really bad answer (3D fix).
Late last year I traded in the Honda for a small truck. As I was designing the robot lawn mower it quickly became apparent that it wouldn’t fit in my little sedan. And even if it could, I’m not sure how I would load and unload a machine that weighs 300lb by myself.
I thought about taking it apart to transport it and then putting it back together in the field. But that is a very inefficient way to do business. The Honda had a great run, it was 16 years old and needed a new timing belt so I figured it was time to upgrade.
I’m a big fan of goals. For my afternoon in the parking lot, here was my to do list:
Figure out the best way to load and unload the robot mower into the truck.
Install my new wheel encoders and make sure they are working robustly.
Play with the RTK GPS modules.
Take the robot into some tall grass and see how it performs.
I realized that I have a few more things I need to bring to the field with the new robot lawn mower, so I updated my checklist of things to bring or do prior to leaving the house:
Cell phone with cellular data and enough storage space for several videos and photos
AA batteries for the RC transmitter
Make sure rover batteries are sufficiently charged
The toolbox with hex wrenches, adjustable wrench, and screwdrivers
Laptop with a good battery charge
Telemetry radio for the laptop
SD card, installed in the Pixhawk
RTK GPS receiver, antenna, and micro USB cable for power
Rechargeable batteries for RTK GPS base station
Prefetch any map data that will be needed in Mission Planner
Preplan any missions that may be needed and save the waypoint files
I typically would have gone to an actual field, but a parking lot offers some really nice geostationary markers that show up on satellite imagery: parking stripes.
My neighbor saw me using chunks of plywood to load the robot in the truck. He had some tailgate ramps he wasn’t using and let me borrow them for the day. I think I’m going to make him an offer for them. They were tremendously easy to use and transport.
The roof of a car makes for an awesome ground plane, so I decided to set up the RTK GPS base station on top of the truck. I noted which parking stall I was in and then found that same stall on the map imagery in Mission Planner and fed those coordinates to the ZED-F9P module.
To get a feel for how the RTK GPS was performing, I ran a circle mission.
On the map, the green line is GPS2, the position solution from the ZED-F9P module on the rover. The blue line is GPS1, the NEO-M8N module. My understanding is the red line is the EKF’s estimation of position after fusing sensor data with the GPS data.
The blue line is offset from the green line, even though their paths are pretty similar. I think this is because I arbitrarily selected the location of the base module. Essentially, I’m using two different origins: one for the RTK GPS versus whatever the M8N uses. This poses a problem when you lose the RTK fix.
The ZED-F9P module doesn’t lose the RTK fix gracefully. It frequently goes from RTK fix to no solution. After a few seconds though it usually returns to an RTK fix. But once it’s lost, the EKF replaces the F9P position solution with the M8N’s solution. Which is off by a few feet.
You can see an example of this behavior in the picture above. The position is heavily weighted to the F9P solution, but once it’s lost, it jumps immediately to the M8N solution. Interestingly, when the F9P reports an intermediate solution such as 3D fix, the weighting behavior is more of an average between the two receivers.
I double checked my parameters and GPS_AUTO_SWITCH = 2, so the EKF should be blending solutions, not just using the most accurate solution of the two. And when both receivers are in 3D fix mode, that’s the behavior you see.
I have some questions based on these observations:
Is GPS blending really that useful? Maybe I should just ditch the M8N module all together. Whenever you have an RTK fix, it seems like this solution is so superior that the EKF basically ignores the M8N solution.
For GPS blending, would an additional RTK GPS help? The reported accuracies from two identical modules would be similar. Maybe the redundancy would help when an RTK fix is lost on one receiver.
Why does the EFK assume the robot’s position suddenly jumps? This is a rover, not a quadcopter. Especially when you have wheel encoders and an IMU, you should be able to assume that the robot’s position isn’t drifting significantly due to external disturbances, even if the GPS position jumps.
If we could eliminate the offset between the two solutions by using the same “datums” would that make the failover more graceful?
Some of those questions can be turned into experiments I can conduct the next time I’m out in the field:
Disable the NEO-M8N module. How does the robot respond when the ZED-F9P module loses an RTK fix?
Instead of arbitrarily setting the coordinates of the RTK base module, we can let it “survey in” to determine its location. This may eliminate some of the offset between the F9P and M8N position solutions.
We can measure the offset between the F9P and M8N solutions and then adjust the coordinates of the RTK base module to compensate. This would minimize the position jump between solutions when RTK fix is lost.
I also took the robot out into some taller grass to see how it would perform. You can see a video of it here. I also took a time-lapse of a typical grid run. Overall not bad, but for striping grass, it’s not good enough.
Going forward it looks like I will need ways to obtain a better position solution. I don’t think RTK GPS will get us there entirely. There are some exciting visual odometry solutions out there I may look into.