Multifacited Autonomous Rover
After move-outs and the conclusion of online semesters in Spring 2020, I sought to take up a new robotics project involving long-range/duration operation. My first idea was to build a long-range RC wing capable of >10 km missions and full autonomy using PX4. Applications for this included surveying, stabilized aerial hyper-lapses, and payload deployment. However, given my proximity to populated areas, flights of this distance would be impossible without flying through controlled airspace or over people. I also wanted to integrate companion computation for more complex behaviors that would not necessarily prove practical on a fixed-wing platform. So I returned to the drawing board to outline my goals for the project and what I wanted to learn:
Initial waypoint missions were a ton of fun! The rover had acceptable efficiency and enough torque at low throttle to maintain a crawl. However, a mission ended up pathing it into some tall grass which damaged the 3D printed bearings within one of the cycloidal actuators. Repairs are underway in addition to the integration of a Raspberry Pi for LTE control, video streaming, and autonomy using DroneKit python.
My ambition for payload modularity and cheap building materials quickly ruled out any sensible aerial vehicle as an acceptable option. While the most capable of long-range operation, fixed wings (especially RC platforms that cost would constrain me to) would not meet the above criteria and prove restrictive when deciding to add intelligent behaviors. For these reasons, I resolved to stick to the ground and build a rover.
One of the first factors that drove my design initially was the idea of theft. Any beyond-line-of-sight operation could be potentially hazardous in this regard so I wanted the design to address this immediately. Of course, sensors and payloads could help with this but I decided to ingrain theft protection into the design which would come first in any case. I began the design process with a simple solution to this issue: make the vehicle just heavy and large enough to discourage snatching it but compact enough for me to use effectively. And so, the construction of the frame began:
I opted to use a full 80/20 construction using 20-2020 profiles for their structural rigidity and ease of assembly. This method allowed the frame to be modular but also rigid without having to weld. I used SolidWorks weldments to create the frame and generate a custom cut list to send for production. The frame itself was designed in 2 levels: a lower level to contain drive mechanisms, batteries, and power electronics and an upper level to house controllers and payloads. Rigid supports were required between the lower and upper levels to mount the drive axles and suspension components. The lower level of the frame needed to be as close to the bottom as possible, to maximize wheel clearance, but not too close as to not leave enough room for the wheel actuators. Lastly, the lower level would have to provide ample room to mount axles such that the wheelbase of the rover was reduced enough to provide better steering characteristics. I was mostly constrained by the dimensions of the frame but referenced the following diagrams to change the wheelbase and track width to optimize steering performance and handling.
Next came the issue of what features I wanted the drivetrains to have. I guided my decision by addressing the architecture of my control system of choice: ArduRover. ArduRover is a branch of the open-source ArduPilot software for controlling drones and other autonomous vehicles. The rover variant uses either a skid or separate steering form of control. I chose to use skid steering with 4 individually driven wheels to maximize torque, traction, and maneuverability. However, this choice was not without its issues as skid steering vehicles require all 4 wheels to have reliable contact with the ground to achieve acceptable turning performance. I had thought it best to simply mount the tires in a fixed configuration but with the intention of driving off-road, other solutions would have the be explored.
My first idea was to pursue to the tried and true rocker-bogie scheme. However, as per my ambitions to keep the project cheap, I had chosen to use my cycloidal actuators with 10″ tires that already had a 3/4″ axle hub. This meant that mounting the actuators near the tires on a rocker-bogie rover would be clunky and result in geometries that would reduce ground clearance while increasing mechanical complexity. My next idea was to pursue articulating drive schemes to allow the rover to maintain good ground contact. The YouTube channel rctestflight shows a neat example of this on a similar rover project. Here, he uses a passive joint in the frame to allow the 2 pairs of parallel wheels to pivot about a central axis, therefore allowing all 4 wheels to have contact at any time. This is an awesome and simple solution but would force me to partition the frame, add nonstandard parts for articulation, and also sacrifice payload volume. As such, articulation was close but not quite what I was looking for.
During my research, I began to read up on Carnegie Mellon’s Crusher UGV. It was designed by their National Robotics Engineering Center (NREC) as a heavy utility vehicle for the army. What caught my eye was its use of independent suspension for each of its wheels that allowed it to crawl over obstacles while maintaining traction. The NREC also developed a smaller version of the Crusher dubbed Mini Crusher. Here are some of the videos of it that guided my research:
My case of using either the rocker-bogie, articulating, or independent suspension drive schemes was quite simple as steering would be controlled by altering the behavior of the motors, not the steering plane of the wheels. For this use case, independent suspension achieved the same result of reliable traction without added complexity or having to sacrifice any of my design criteria. Moreover, its simple construction would allow me to source parts from hardware stores while only having to machine simple components. For these reasons, I chose to make the rover’s suspension system independent.
The next important constraint that I set for myself before designing the suspension and drive systems was material choice. In addition to 3D printed parts, I opted to use 1/2″ steel square-tube stock for suspension support members, 3 mm aluminum stock for machined components, and 1/4″ threaded steel rod for pivot points. These materials and other basic hardware components were readily accessible at local hardware stores, easily manufacturable, and cost-efficient for the scale of 4 wheels. With that, I also opted for a basic rendition of a dual wishbone suspension using 2 pairs of control arms. The following media shows this prototype suspension and other systems that I will describe further such as the shock absorber, drive axle, my custom cycloidal actuator, and axle to wheel interface.
The interface between the control arms and the frame was fairly simple: aluminum brackets fixed to the 20-2020 profiles to provide a pivot point on the frame while their attachment to the hub gave the wheel support and ground clearance. I iterated a few designs using motion studies and assemblies to determine which lengths would provide good clearance and favorable camber angle change (with travel of the suspension). At the same time, I was also working out how to extend the drive shafts from the actuators to the lower level that I had put the wheels on. Again, I preferred not to mount the actuators to the wheels because of their size so I opted for a 3-piece driveshaft with 2 universal joints. This gave the design the ability to transmit power to the wheels, while keeping the actuator inside the chassis, and allow the drive axle to move up and down with the suspension.
Next came the interface surrounding the wheel hub, drive axle, and wheel. For this, I decided to use a full-floating axle in order to reduce normal forces/bending moments on the drive shaft. Ideally, the only forces on the drive should be torsional, and knowing those would be more than enough for it to handle, I actively avoided semi-floating configurations. A full floating axle avoids such forces by using a bearing between the spindle and wheel hub to support the weight of the vehicle. This contrasts from semi-floating configurations which directly fix the axle to the wheel hub, therefore subjecting it to torsional and bending loads. While using a full-floating axle was more complex, its use would give the rover excellent carrying capacity.
Moving forward with this axle choice, I began working on the spindle-wheel hub connection. Ideally, large roller or wheel bearings would be used but because of their high cost (not to mention lack of justified use at the low RPMs I’d be dealing with), I needed an alternative. My first solution to this was to FDM print multi-part roller bearings in a single piece by adjusting the tolerances. My iterations for this can be seen below:
The roller bearings were parametrically designed to slide over existing wheel hubs. In order to print them as functioning assemblies, I progressively increased tolerances between the rollers until they spun freely without any post-print cleanup. Silicone-based lubricants also helped to reduce friction. However, prints proved unnecessarily difficult and even with the best tolerances, there was always lateral slop. It became clear that even with at a high resolution, fully printed bearings could not achieve the fit needed to reliably fix the wheels. At this point, I referenced the ball bearings within my cycloidal actuator as a means to simplify the printed geometries for the ‘floating’ part of the spindle. Following this design method, I replaced the 3D printed rollers with stacked rings of airsoft BBs which vastly simplified the printing process. BBs could be easily inserted using an arbor press and the result was a total lack of lateral slop with the wheel hub. Here are some videos to compare the V2 (fully printed) and V3 (with BBs) bearings as well as a render of the V3’s internals!
With the success of the bearing design, the final design of the fully-floating assembly could be completed. The picture below shows the first version of the suspension (albeit without control arms and the V3 wheel hub bearing).
Before discussing the improvements that were made to this assembly, I want to discuss my choice of a shock absorber. After looking into existing minibike and RC models, most were either too large or too expensive to be practical for this project. Additionally, I did not need a damper within the shock and this was what usually drove up the cost of commercially available models. So, as was rapidly becoming the gist of this project, I chose to design my own. I sourced a variety of springs from McMaster-Carr with an assumed 20 kg total weight of the vehicle. I needed to make the design of the shock dynamic to accommodate different springs as I had no way of knowing what the weight of the vehicle would actually be at this point in the design process. With this in mind, I came up with a simple shock (basically a spring holder) with a hand-adjustable nut to change the loading conditions/clearance of the wheels.
All that was left to complete the first iteration of the drive was the power transmission between the actuator and axle. I opted to use series double-helical gears for maximum power transmission and to eliminate any axial forces along the drive. Using a simple 1:1 transmission, the actuators could now spin the wheels!
At this point, I was really excited by the progress of the drive but definitely needed to address and correct a few issues. In my excitement during the first test, I thought “Hm… how much torque is the wheel really seeing?” as I put my hand on the tire to restrict its rotation. Instantly, I heard a ‘crack’ and several plastic remnants of the universal joints fall to the floor. The cycloidal drive had effortlessly twisted the ABS prints apart, and I laughed as I returned to the drawing board.
I tried a few ways to improve the joint design such as increasing infill and wall count but no parts could withstand the forces to even back drive an unpowered actuator (which was very doable by hand). I also noticed a few deeper and more concerning problems: the first of these being the fact that as the control arms of the suspension moved and the axle joints flexed to follow, the joints would actually pull themselves apart and crack along the print layers. This indicated a fundamental flaw in my calculation of the control arms whose lengths and mounting points failed to coincide with the axle. The second issue, as another indication of improper arm design, was that as the suspension traveled upwards, a positive camber angle developed. In any case, the undisturbed state of the tires should be as close to a camber angle of 0 degrees as to maintain maximum traction. But with a slightly positive camber angle under load, this suspension would force the tires to slide inwards when moving over objects. Such a result placed unnecessary forces on the suspension, notably the spindle, and would need to be corrected to a negative angle in order to facilitate maximum traction when the tires rolled over objects. Lastly, the entire assembly had an annoying amount of slop as a result of poor hole tolerances, the V2 printed roller bearings, and poorly supported right-angle 20-2020 brackets which were the fixture points of the control arms. To solve this, I would have to eliminate unnecessary tolerances and begin machining custom aluminum brackets for the control arms.
I acted on recalculating the control arms first to constrain further solutions. Instead of looking into complex equations to drive control arm lengths, I opted to simply make the top pair of arms slightly shorter than the bottom. This gave a desirable negative camber angle under load and made machining the control arms much easier. Furthermore, instead of constraining myself to off-the-shelf 20-2020 brackets, I chose fixed points for the control arms on the rover chassis that gave me ideal suspension behavior. Only after this did I design custom, but simple plate brackets to support the bolt holes of the supports. In this way, I could utilize the precision of a CNC router to accurately place holes with complex dimensions while keeping the dimensions of the steel control arms easy for hand cutting. With that, it was time to take an extended field trip to my family’s shop.
Having constrained the control arm geometry, the only issues left all concerned the universal joints. The first step was a redesign to make the joints bulkier in an effort to reduce the fracture point at the base of the grips. I also integrated small ball bearings into the joints themselves to make assembly more reliable and reduce friction. When thinking about the layer separation of the joints, I stumbled across an RC car design that used telescoping universal joints to make up for misalignments between the wishbone control arms and the axle. I decided to apply this to my design by allowing one of the joints to slide over a member of the drive axle, therefore alleviating stress on them during movement of the suspension. The following iterations of the joints (yellow prints) tested this theory. Reference this video above to see the telescoping joint in action when the suspension is moving.
These revisions concluded the improvements to the rover drive and allowed for a working V3 to be produced. Here is a quick test video:
Also during this test, but after the video, I successfully back drove the actuator from the wheel! My modifications to the joints were successful but not out of ABS as the parts did not survive multiple attempts. As I transitioned into a phase of manufacturing the bulk of 3D printed and machined parts, I opted to print these joints and certain parts of the actuators out of Alloy 910 because of its awesome tensile strength and ability to decrease noise in geared mechanisms.
And just like that, we’ve reached the current state of this project. Such a huge manufacturing bottleneck with 3D printing was not anticipated but final parts are on the way! In the meantime, I’ve begun developing the rover’s control scheme. I will conclude with a brief description of my work on that so far!
My main motive in designing this rover was to make it a vehicle for testing all sorts of algorithms and payloads. In doing so, I’ve set out to practice applications of companion computing with Pixhawk flight controllers, learn Python and ROS 2, and perform SITL simulations using Gazebo. Having a complete rover assembly, I began with Gazebo simulation using the SolidWorks to URDF converter: SW2URDF. This add-in allowed me to export URDFs (universal robot description format) of visual and collision models for my rover which could then be converted to SDF files for easier use in Gazebo. Here is the complete rover model in a virtual environment!
In order to control the rover, I used DroneKit Python with ROS 2 and ardupilot-gazebo to execute example scripts and send simple MAVlink messages to test the functionality of the model. However, as is apparent within the second video, this is still a work in progress as I learn more about these awesome software development tools!
My current plans for the project are to complete the assembly of the remaining 3 wheels and actuators. At that point, I will assess the dynamics of the suspension/drive and use Pixhawk waypoint missions to perform endurance tests. My initial goal is to utilize DroneKit to build an infinite waypoint mission that the rover will follow while recharging itself using solar panels. Other applications that I’m pursuing are an assistive robot that follows and carries heavy items and a chalk drawing robot to translate G-code to huge landscape portraits in fields/parking lots. I plan on posting more updates to this page as I progress so stay tuned!
Following software configuration and somewhat extensive tuning, the rover was able to perform its first autonomous mission! I plan on posting a more detailed description of my work between the assembly and this point but for now, here is a video of the most recent test.
Initial waypoint missions were a ton of fun! The rover had acceptable efficiency and enough torque at low throttle to maintain a crawl. However, a mission ended up pathing it into tall grass which damaged the 3D printed bearings within one of the cycloidal actuators. This damage was a result of stress concentrations within the actuators which were amplified by the friction of the grass during skid steering turns. So, in addition to repairing the damage and fixing tolerances of the gearbox, I sought to give the rover bidirectional control to reduce these stresses during turns.
This build used a BLHeli_32 electronic speed controller (ESC) which features a rich set of parameters for custom programming. Among these is a bidirectional setting for mapping forward and reverse control over a PWM signal with a pulse width of ~1000 to 2000 μs. Previously, the rover could only travel in one direction with a full 0-100% throttle range mapped over 1000-2000 μs. However with this setting and some adjustments of parameters in ArduRover, bidirectional control was possible with reverse mapped to 1000-1500 μs, neutral (stationary) at 1500 μs, and normal forwards at 1500-2000 μs. Some of the research that I conducted to achieve this method of control can be found on the ArduPilot forums here!
In addition to mechanical repairs, a Raspberry Pi was added for autonomy using DroneKit python. Initial bench tests of a Python waypoint mission were successful over a USB connection. In the near future, I plan on adding video streaming and LTE control.