Now that the dust has settled on this year's PiWars competition and we've had time to lick our wounds it's time to look back on our PiWars journey and reflect on what went well... and what didn't go quite so well.
Let's go through every aspect of the PiWars process in turn, rate ourselves out of 10 and ask some searching questions about how and where we could have done things better.
This post is intentionally long and detailed. If you're just interested in the scores on the doors, see our summary post instead.
SUMMARY: Well-supported parts from well established suppliers. We'd use everything again.
Early in the design process we had to nail our colours to the mast and settle on the hardware that we would use for our robot. In the end, we chose the following:
- Motor Controller: PiBorg Thunderborg
- Motors: PiBorg MonsterBorg 12V, 300RPM
- Motor Brackets & Wheel Adapters: PiBorg
- Distance Sensors: Pimoroni Breakout Garden ToF (VL53L1X)
- Compass: Pimoroni Breakout Garden 6DoF (LSM303D)
- Line Sensor: Robo:Bit Buggy Line Follower Sensor Pack
- Status Display: Pimoroni Breakout Garden OLED (128x128)
- Camera Attachment: Pimoroni Pan-Tilt HAT
- I2C Multiplexer: Adafruit TCA9548A
- Wheels: 96mm Diameter RC1:10 Rock Crawler Tyres
ChOICE OF PARTS
Our choice of parts was one of our best decisions. We couldn't have chosen better. The parts worked flawlessly together.
CHOICE OF SUPPLIERS
We experienced the odd faulty component (who doesn't?) and it's fair to say that we broke one or two things ourselves along the way through careless handling. The suppliers (Pimoroni & PiBorg) were absolutely faultless in their customer service, swapping errant/borked parts out without question.
Our Advice: If you are a beginner, go with well known suppliers for all the major components. The support & customer service alone will pay for the cost differential many times over.
The wheel size (96mm) was a saving grace on the rocky terrain of the Spirit of Curiosity challenge. We chose the Rock Crawler tyres based on the recommendation of a veteran competitor, David Booth (@Worlds6440) and we were not disappointed. Another experienced competitor also commented on how he wished he hadn't gone smaller than us with his wheels this year.
Our Advice: Go large and grippy. RC1:10 Rock Crawler Tyres are a great choice.
Our choice of motors (12V, 300RPM PiBorg MonsterBorg) proved to be an ideal combination of both speed and torque. We heard a horror story on the day from Sumit Maitra (@pi_of_things) who opted to go all-out for speed this year with faster 1000 RPM motors. This was at the cost of torque, and ultimately his robot, as it got stuck in the obstacle course and his battery box melted.
Our Advice: Torque is king. You will get a top 5 placing if you complete all challenges, regardless of speed.
The sensor choice (Pimoroni Breakout Garden range) was inspired. From what we could tell, loads of people were using these sensors... including some of the veterans. Being manufactured by Pimoroni meant that we could leverage their example code for ease of learning how to use them. One of the pirates (Sandy Macdonald) even offered to develop some example code for calculating compass bearing from the Gauss magnetic vector data that the 6DoF sensor was reading when we asked for support on this.
Our Advice: If you are a beginner, stick with the road most travelled. You will find a lot more example code and get a whole load more support if you get stuck.
Although we have a pan-tilt camera attachment on our robot, we never officially selected a camera because we had written off camera usage (and sacrificed the Nebula challenge) early on due to lack of team resource, hence the markdown to 9.
Our Advice: Pay extra for a Pixy2. The Pixy2 seemed to be a popular choice this year as it neatly sidesteps the complexity of openCV.
TOOLING & MATERIALS
SUMMARY: We were happy with the upscaled DIY approach that we adopted. Good use of tools available in our tool box.
Not having easy access to 3D printing and laser cutting facilities we chose to adopt a more traditional DIY approach to everything. One team member already had most of the DIY tools necessary for fashioning a robot chassis from raw DIY materials in his cellar. This toolset included the following:
- A tape measure
- A drill with drill bits going down to 3.5mm
- A jigsaw
- Plenty of hand saws
- An electric sheet sander + rolls of sandpaper
- A Black & Decker Workmate workbench
- A bradawl
- A Stanley Knife
- Screwdrivers, large and small
- A Pipe Cutter
The only tools we needed to buy were a wire stripper and crimping tools.
We failed on the crimping tool side - our order late in the day for a dupont crimping kit arrived as a box of dupont connector parts but was missing the promised crimping tool. With no time to resolve this issue we had to revert to using pre-made du-pont wires, carefully pulling off female connectors where necessary to convert gender at one end to male. We had to daisy chain one or two of our dupont wires to reach the extremities of our chassis - for this reason we have marked ourselves down slightly.
The majority of our materials were spare DIY materials available in the cellar of one of our team members or upscaled scraps reclaimed from bins/skips:
- Chassis: 6mm plywood stripped out of a bathroom during a refit
- Pi standoff: offcuts of plastic plumbing pipe
- Pi battery bracket: corner brace ironmongery
- Chassis layer pillars / sensor mounts: joinery connector blocks
- Wiring looms: electrical connector blocks (chocolate blocks)
- Wires: discarded industrial cabinet wiring from work
- Cable management: electrical splicing tape + carpet staples
- Anti-slip "washers": tap washers
We've marked ourselves down for the plastics and laser cutting we adopted for our sensor mount solution. They were functionally perfect for our needs but not in keeping with the upscaling ethos we were adopting. With extra time, we'd like to have thought a bit more about this design aspect and come up with a truly make-do-and-mend DIY solution.
Our Advice: You don't need access to laser cutters and 3D printers to build a competitive PiWars robot. It can be quite rewarding to fashion a robot by hand. Thinking outside the box with traditional DIY tools and materials can be fun.
CHASSIS DESIGN AND BUILD
SUMMARY: PROS: Well thought out layout, easy to maintain, boxy but robust. CONS: Breakable parts exposed at the front & back. Weak point on front of chassis. Attachment support needed improvement.
Our chassis design was very carefully thought out. Some of our better design decisions included the following:
All batteries located in the centre of the chassis. We also followed the well documented advice and kept our battery weight as low as possible. These decisions resulted in excellent ride stability. Our robot ride was quite bouncy at full power, with a tendency to do wheelies on occasion. Yet it never flipped or toppled.
Our Advice: keep your battery weight central and low for stability
With little prior soldering experience we adopted a "solder only if you have to" approach to our build design.
We used Pimoroni Breakout Garden adaptors and dupont cables to avoid the need to solder our Breakout Garden sensors. This presented us with a risk with respect to robustness of connection. The perceived wisdom from the PiWars community is that dupont connections are notorious for coming loose in the rigours of battle.
We solved this by designing a sensor casing solution to hold the combination of sensor and breakout garden adapter together and provide cable strain relief for the dupont cables. This casing also provided us with flexible mounting options in terms of height and orientation.
We reached out to an associate team member Kerry Kidd (@RaspiKidd) who provided us with the necessary contacts in a local makespace to design and cut the casings for us. Our requirements specification supplied to them was good enough to result in a perfect product first time. Just as well... as we had no time for iteration at this point.
Our Advice: Wires that can't accidentally get pulled apart are far less likely to come apart during battle. Either solder or provide strain relief.
RASPBERRY PI PLACEMENT
Learning from a lot of other people's frustrations around inaccessibility of their Raspberry Pis we made sure that our Pi was accesible, at the back of our robot. Plumbing pipe standoffs were also used to allow for easy SD card removal. As we were planning of adopting a policy of swapping SD cards to switch modes for simplicity (we ran out of time time to consider coding up our preferred solution of triggering a mode switch from a joypad button), accessibility of the SD card was of paramount importance to us. As it was, we didn't get as far as completing more than one mode of operation (remote controlled). More on that later.
Our Advice: Make sure your Pi is accesible and the SD card easily swappable.
LINE FOLLOWING ATTACHMENT
Nice design. Great upscaling of old quarter circle beading from a bedroom refit. Easy attachment & detachment.
MULTI-LAYERED CHASSIS DESIGN
The competition rules stated a maximum size of footprint (300mm x 225mm) but they say nothing about height. Inspired by the principles of skyscrapers, we adopted a two-layer design. The upper layer gave us additional mounting space real-estate for our components. We housed the camera, pan-tilt HAT and motor contoller board on the top layer and the power bus and 6DoF sensor underneath.
The upper layer also usefully provided us with a secure housing for our motor battery pack, by standing it up in a tight-fitting cut-out. As well as this, it provided us with additional secure mount points for our OLED screen and robot costumes (the costumes were our kids' contributions to the project, made out of craft materials and techniques).
Our Advice: If you can't build OUT, build UP... but keep stability in mind.
Not everything we designed turned out well. Here's a summary of aspects of design & build that we could have improved upon:
FRONT SENSOR EXPOSED
While the side-mounted distance sensors were protected by being sited between the front and back tyres, the front distance sensor was left exposed to the elements. By competition day the casing for this sensor was broken on BOTH of our robot platforms due to the robot being driven into things. In hindsight, we should have designed a front bumper to take all the strain on crashing.
PI POWER CONNECTOR EXPOSED
To maximise free space on the chassis we sited the Pi at the very back of the chassis. This meant that our power cable overhung the back of the robot. We managed to bend the Pi power connector on one of teh robots be reversing it into a wall. Again, a bumper at the back would have been sensible.
CHASSIS WEAK POINTS
Our ply-based chassis had a weak point at the front: a narrow strip of ply on our top layer. We had attached a potentially load bearing part to this (the PiWars attachment and Space Invaders push plate). This eventually snapped during the Space Invaders challenge.
The weakness was partly the result of schoolboy errors in the build process that compromised the ply on one side. In our rush to finish the build, we forgot to clamp a piece of wood underneath when drilling out the bolt holes.
Looking back, we could have mitigated this by (a) being more careful when drilling (b) strengthening the chassis with varnish (c) spreading the load by mounting our attachments to both top and bottom layers (see discussion below). In fact, a combination of all three would have been perfect.
Our Advice: Your robot is only as robust as its weakest point. Stress test your robot to find its weaknesses and make it more robust.
PIWARS ATTACHMENT DESIGN
Our solution for mounting the PiWars attachments was to bolt a vertical piece of ply to an L-bracket hung from the front of our top layer. This was a last minute hack ("Oops! We've forgotten about the PiWars attachment. Better come up with a solution and quick!"). This saved our bacon in respect of 3 out of the 4 remote controlled challenges. However, it was a flawed design in two respects:
- It had a tendency to pivot on impact at speed
The bracket was attached to a weak point on our chassis. Pivot pressure on the bracket created a shearing force on this single mount point and eventually snapped it during space invaders (thankfully not fatally).
- It had a tendency to droop when the bolts come loose
During our second Pi-Noon battle we suffered from a significantly drooping joust because the team hadn't checked and tightened the bracket's fixing bolts. This almost certainly contributed to us losing that battle on a judge's decision.
There was a solution to this that we hadn't spotted until afterwards (isn't that always the way?). We should have bolted the attachment to two separate mount points located on the top and bottom chassis layers. This would have had the following benefits:
Load-Spreading: our chassis may not have snapped during the Space Invaders challenge.
Rigidity: the joust may have remained more upright under the loose bolts scenario we experienced.
Our Advice: Make sure your PiWars attachments are robust under strain and are forgiving to the loosening of bolts. Regularly check for and tighten loose bolts before each challenge.
SUMMARY: Tidy, well planned routing. Robust. Well secured. Excellent cable strain relief. Good separation of power and data lines. Could have been tidier and without cable joins with wires cut to size and crimped.
We were very happy with our final wiring plan. We separated data and power cables as much as possible, even going as far as having separate data and power holes in our chassis layers for passing wires between layers e.g. from the motors and line sensors on the underside.
Cable management made innovative use of electrical splicing tape to both gather bunches of wires and protect them from the staples securing them in place on the chassis. Sensible cable management also provided useful cable strain for dupont connectors on the multiplexer and the Pi. As a result of this we suffered no loose wiring issues on the day.
We were particularly pleased with the way that our wiring on the top layer was routed to allow us to hinge the top layer off to access the lower layer.
We asked Dr Lucy Rogers if we could have improved anything on our robot. After a long pause she said that slightly tidier wiring might be nice but that it was difficult for her to see how we could have achieved that on our robot. Actually, we do know how: we could have cut our own wires to precisely the lengths that we required and not relied on fixed length dupont cables throughout. Alas, our reliance on pre-made dupont wires was because our last minute order for a dupont cable making kit disappointed us by only including adapters and pins... and NO crimping tool!
Our Advice: Plan your wiring carefully. Separate power and data wires as much as possible. Secure your wires. Minimize your cable joins and provide cable strain relief for any joins in the wiring that are liable to come apart.
SUMMARY: Unnecessary learning overheads introduced by adoption of a Rolls-Royce solution where a Mini would have sufficed.
Early on in the development process, one of the team members argued passionately for using Robot Operating System (ROS) on the basis that it comes with a robust pub/sub messaging architecture out of the box. It was argued that this would make things simple for managing our sensor and joystick data.
In a world where we had plenty of time to familiarise ourselves with the ROS architecture (no-one in the team had used it before), a significant amount of sensor data to manage and lots of motors to control this would have been an admirable choice. Afterall, it was built with complex robotics in mind. In the end, we never leveraged the benefits of ROS so this proved to be nothing more than a distraction.
In fact... with little time left to learn how to leverage the ROS messaging architecture, one of the team members easily managed to code up a round-robin of all sensors on a Raspbian image which wrote its data readings out to a JSON data file. We were then able to read this JSON data from a proof-of-concept maze solver process (decison making, but without motor movements). This underlined the fact that we didn't really need ROS in this particular instance.
We chose to use a Ubiquity Robotics build of ROS, the installation of which caused us some problems. Raspbian would have been perfectly adequate for our needs and is known to work out of the box on the Pi. Moving away from the widely supported route travelled by many a PiWars competitor also made seeking advice more difficult when we hit problems, delaying our progress.
In the cold light of day, this decision would not have passed a cost-benefit analysis. From what we have heard anecdotally, over-engineered solutions are not an uncommon problem in the PiWars world.
Our Advice: If you are a beginnner, aim for the simplest viable software solution possible. Adopt whetever represents the lowest learning overhead for your team. Aim to just get things done - worry less about getting things done "well". The principle of MVP is king.
SUMMARY: Solved in theory only, not in practice. Ran out of time.
As a team, we knew conceptually what needed to be done here to solve the autonomous challenges. We had purchased the necessary sensors and camera pan-tilt, built that it into our chassis and tested that we could successfully request data from all the sensors. However we ran out of time to do anything with this data once we had finished building the final competition-ready robot platform.
The points we score here are purely down to preparing the groundwork and testing end-to-end sensor readings only. We score zero for the algorithms themselves as they were neither completed nor tested and thus we had to pass on all autonomous challenges.
One thing that hampered our team was that we did not take the time and effort to fully understand the example joystick control code provided by Piborg early on in the process and leverage that to build our own simple motor control class library early on. Instead, due to insufficient time and human resource, we adopted a fall-back strategy of blindly relying on the PiBorg example code for our remote controlled challenges.
When we found ourselves writing line following and maze solving code with only a day to spare, our lack of knowledge regarding how to work with the Thunderborg controller prevented either of these pieces of autonomous code from being completed in short order. The maze solving code was 80% written and tested as working in principle with simple log messages being triggered in place of motor instructions. With a little more time to build a simple motor control class we would have got there.
Thinking about this some more, while we were quick off the mark with our early test build, we significantly under-utilised this advantage. We had all our sensors at the beginning of December yet did nothing with them for 2 months. In fact, we only got around to soldering our multiplexers by the end of January. We should have soldered them much sooner and immediately set about coding up basic solutions for the autonomous challenges with our test build, sellotaping or blutacking sensors on if necessary. Instead, we left all the autonomous code writing to the very end and then ran out of time. Not an uncommon position for a PiWars team to find itself in... apparently!
We now have in our possession a simple but effective class library and sample code for instructing the motors to go forwards, backwards, left and right. This was kindly emailed to us the night before the competition by another competitor (Thanks Gaby!). If we weren't so sleep deprived by then, we might have been able to use it.
Also, in the final days leading up to PiWars, Pimoroni's Sandy Macdonald solved the conundrum of turning gauss magnetic vector data on their Breakout Garden 6DoF sensor into compass bearings so we would have been able to rotate exactly 90 degrees. Thanks Sandy! Alas, there was neither enough time nor mental energy remaining on our team to leverage that. However, we did pass that intel on to another team using the same sensor who did manage to benefit from it. Yay!
Our Advice: Start working on prototype solutions for autonomous challenges as early as possible using your prototype/dev platform. A clunky solution is better than no solution at all. The only development that should be occurring towards the end are fixes for things that cease to work as intended on your final platform and refinements to already working code.
SUMMARY: Underestimated the challenges. Lack of initial discussion regarding individual skills and knowledge, no clear division of responsibilities, resulting in skill and knowledge being too concentrated on one person.
We started out as a team of 2 families with plans to get our kids learning how to build their own robot.
There was an early attempt to propose a division of responsibilities amongst the parents involved. A project document was written that suggested project roles but no-one provided feedback on that proposal and the idea to assign clear project responsibilities was soon forgotten in the mists of time.
As time wore on, what had started as a project involving 2 families became a project involving only 2 people (and no kids). This was because lack of prior experience made it difficult to carry the kids with us.
Furthermore, as time ran short it became apparent that the lion's share of the technical knowledge and experience lay with only one person and, rightly or wrongly, that person really began to feel the pressure of responsibility for the eventual success or failure of the entire team.
If there is one thing we would do differently next time around, we have an honest discussion about the skills, knowledge and experience that everyone can bring to the table at the outset with a view to constructing a team with a reasonable spread of skills. Team members should agree to take on a particular set of responsibilities at the outset that are consistent with their skill set and be prepared to stick to that.
Perhaps one way we could do this would be to construct a questionnaire for everyone to fill in which covers all the key skills required for such a project (now that we know a little more about what they are). We would even go so far as to say that it is more important for team members to be brutally honest about what they can't do at the outset than what they can (or might be able to) do. It's better that the team knows it has an area of skills shortage at the outset so that it can do something about it. Finding out about a skills shortage at the 11th hour is no fun at all!
Our Advice: Have an honest discussion about skill sets at the outset. Where possible aim to spread your skills across the team. Agree a clear division of responsibilities and stick to that.
SUMMARY: Started well. Ended badly. Plans scuppered by personal circumstances.
We started well, with a project document containing key milestones and identifying key risks. However, as the project team shrank in size that project document got left behind, as did any concept of project management.
Through the process, both remaining team members hit rough patches at work and eventually quit their jobs. For one team member, the 3 month notice period proved to be very painful indeed, leaving him unable to make progress with the PiWars build. For both team members, significant time had to be put aside for CV writing and job hunting.
As a result of these diversions, there was a 2-3 month hiatus in substantive PiWars progress and the team found itself with a final robot platform still to build with only a month to go. Ouch!!! We did remarkably well building a robust platform in such a short space of time but we really could have avoided finding ourselves in this position.
Our original milestone plan from the project document should have been regularly revisited and adjusted as necessary. By regularly reviewing our progress against our plan we would have seen the crunch coming and been able to do something about it sooner, perhaps seeking to recruit an additional team member to take up the slack. This may have bought ourselves enough additional time to attempt at least one autonomous challenge.
We give ourselves points for starting well and limping across the finish line with a complete build and a robust platform, but we have to admit that we didn't finish well, having to ditch ALL autonomous challenges.
Our Advice: Have a project plan. Assess progress against plan regularly. Adjust plans as necessary. Be open to seeking additional help if necessary.
SUMMARY: Started late due to ambitious self-hosting plans. Should have posted little and often. In the end, we only scraped across the line by virtue of a significant last minute push by one team member to replicate and expand upon his regular progress reports on Twitter.
We chose to build our own blogging platform on a Pi. This meant that we didn't have a stable blogging platform until Christmas. This delayed the start of our blogging effort. Perhaps we could have been less ambitious and just signed up to one of the many free online blogging platforms.
We also didn't agree a clear blogging strategy beforehand. This resulted in the blog being largely overlooked and 90% of the content being posted at the very last minute, based on a historic trawl of the Twitter history of one of our team members. If we weren't able to leverage and expand upon this tweet history the blog would have ended up looking very sparse indeed.
In hindsight, we would have benefitted from having sufficient resource to put someone in charge of the blog at the outset. That person would also be responsible for taking photos and videos to post up on the blog. That person does not need to be involved in the technical aspects of the project. In a way it might be better if blogging is their only focus. This little gem was gleaned from a chat over beer with @MyITInstructor (Kerry Bruce) - this is exactly what he does in his team (CNM HackSpace).
Our Advice: Consider seeking a non-technical team member to be in charge of all blogging activity, including obtaining photos and videos. Post regular (e.g. fortnightly) progress reports whether or not progress has been made.
SUMMARY: A complete lack of non-functional testing. Build quality saved the day.
We did plenty of I2C and joystick comms and motor tests along the way. Buzz testing of all the wires was a particular favourite of ours - this was great for quickly getting to the root cause of any I2C comms issues. However, we simply ran out of time for physical robot stress tests and driver practice as the final robot platform had only been completed a matter of days before the competition.
We score ourselves for comms / wiring tests only. Everything else was simply missing in action, a consequence of lack of time. Any issues we discovered ahead of time were a result of timing and luck only.
For instance, it was a stroke of luck that lead us to take our main robot out of its box at the venue the day before the competition. We only did so to help troubleshoot problems that we had encountered with our backup robot where one of its motors would start spinning for no reason. In doing so, we decided to hook it up to a controller to give one of our potential robot controllers his first go at the controls. Yes... you read that right... he hadn't driven our competition robot until the day before (another testing shortcoming of our team). During driving practice he managed to lose all four of its wheels (not all at the same time we hasten to add - that would have just been comical). Only then did we realise that ALL the wheel adapters had been wrongly fitted in the first place (the motor spindles are D-shaped for a reason). Things could have been soooo different on competition day had we not encountered this problem when we did.
We hadn't tested our bowling performance either, let alone with the correct sized balls. In hindsight, we should have purchased at least one example ball using the link provided by the organisers. As it was, our robot kept running over the balls because the plate was set a wee bit too high and it was only secured at the top, allowing it to pivot a wee bit under the force of impact at speed. Despite its height above the ground the plate also occasionally snagged on the floor as our robot had a lot of bounce. Had we lowered the push plate, the front of our robot chassis would almost certainly have been pulled apart. We think we barely scraped by (no pun intended) with our chosen push plate height on the day. Any higher and we would have failed to score at all, any lower and we would have risked pulling our robot apart.
The joust and sample bowl attachments could have been more robustly constructed, tested and refined as well. However, we were lucky to have anything at all given how short of time we were.
Our Advice: Non-functional testing (robustness, comms reliability, driver expertise etc...) is just as important as functional testing (rc handling, autonomous behaviour).
ON THE DAY STRATEGY & PLANNING
SUMMARY: Missing in action.
There is no getting around this... we were absolutely woeful on this point.
There was no pre-competition strategy discussion. No discussion of who would be responsible for preparing the robot for each challenge. No decisions regarding who would be controlling the robot for each of the RC challenges. No scenario planning. No agreed timetable of team activities. No pre-challenge checklists. Nothing.
As a result of this, our Spirit of Curiosity preparation was unnecessarily rushed as no-one had thought to check that we had a robust attachment on the front of our robot. As a result of this we were still trying to fashion one with 5 minutes to go.
We also struggled in both rounds of Pi-Noon that we were involved in. In round 2 we had to reseat the top layer of our robot as noone had noticed that it wasn't even bolted down. In round 3 our joust had to be held in place with copious amounts of gaffer tape because it had worked itself very loose in round 2 and no-one had checked and tightened it up. Our robot operator also reported that our robot was less responsive because we hadn't thought to give it a fresh set of batteries. Having an on-the-day strategy that assigned personal responsibility for preparing for each challenge and specified a pre-challenge checklist to run through would have prevented many of these issues.
We are scoring ourselves a big fat zero here because we were only saved on the day by (a) luck (b) copious amounts of gaffer tape (c) one very able robot controller who was handed control in some challenges as they began to flounder. Planning and strategy played absolutely no part in our performance on the day.
Our Advice: Consider having a clearly documented on-the-day strategy that assigns responsibility for preparing for each challenge, defines a pre-challenge checklist, specifies who will control the robot for each RC challenge and provides solutions for a realistic range of potential failure scenarios.