BunnyBots Season Recap
Finalists! This was our first finalist appearance as a team since 2018. Thank you to teams 3711 Iron Mustangs, 6831 A05-Annex, and 2898 The Flying Hedgehogs for making up a killer alliance with the top two high scores of the competition! Congrats to the winning alliance of 2471 Team Mean Machine, 4043 Nerd Herd, 2733 Pigmice, and 3636 Generals! You all were a blast to play against, and we loved getting to see your amazing robots in action.
We went for an ambitious design with 5 new concepts for team members: a swerve drivetrain, pneumatics, chain, an over the bumper intake, and an elevator. Everything except for the swerve modules was machined in-house and assembled in record time. We learned a lot about our machining capabilities. As well, we had to figure out how to work efficiently and productively while still teaching our newer members how to be contributing members of our team and our community in general. We chose to build a very ambitious robot and we learned a lot from it. Last season SERT was focused on being able to compete and have a robot at all, but this season we are lucky enough to be able to start thinking about how we can build better and more complex robots. We’ll be summarizing an entire build season in one post, so buckle up!
Kickoff Process
Through the 3-meeting (2 hours each) process, we ran through a presentation linked here. We started with a brief overview of goals and things to keep in mind while reading the rules, then we read relevant sections, followed by filling out this worksheet (Adapted from a similar sheet by 2791 Shaker Robotics) in small groups. After this, we created a list of robot roles as a whole group, which we then ranked. We then brainstormed more specific robot attributes (still not mechanisms), and organized those into needs, wants, and luxuries. Next we ran through a quick presentation on mechanisms (thanks to team 6328 for some of the images) to familiarize our newer members with some good examples. We then broke up into groups of ~5 to draw up robot/mechanism ideas, roughly evenly by experience. When this was done, each group presented their design to the full team, allowing us to discuss as a group which designs to eliminate until we had 2-3 to prototype for each subsystem.
Overall, this process worked pretty well for us, but the processes for robot role and attribute brainstorming and organizing felt a little long and repetitive at times. The mechanism presentation felt quite useful, but it does need informed explanation to go with the pictures. Going forward, we hope to streamline things more in all aspects, which just comes with practice. The rules worksheet was also difficult to get participation on from new members, so we may make it shorter in the future. We also could’ve done better on revisiting our priorities for robot roles and attributes, which would’ve allowed us to change them over time and keep them as a guideline for our design process.
Prototyping Process:
We started with very rough plywood prototypes of individual subsystems made by groups of students, each with a student lead, then followed up on these prototypes with further iterations cut out of ½” plywood on our CNC router, including slots for bolts and multiple sets of holes that allowed for adjustability. As we nailed down certain subsystems, our prototyping became more and more refined within other prototyping groups. This iterative prototyping process is something we haven’t done a whole lot of in past years, but was a specific goal going into this build season.

Above: The CAD for our first CNC intake prototype, using a combination of slots and bearing blocks to quickly nail down dimensions that allows it to be held against the bumpers of an old KOP drivebase for quick testing.
Major takeaways:
The rough plywood prototypes were a good starting place, and the adjustable ones made on the CNC were super useful as they allowed us to dial in dimensions for things like intake compression within a single prototype iteration. The only thing we would really change about that is using higher quality, thinner plywood (like ¼”) instead of ½”, which would be quicker to machine and hold up slightly better. Our iterative prototyping process yielded much better results, and allowed us to make much more informed decisions. This was crucial in a game that included such unique game pieces. Not doing any integrated prototypes was definitely our biggest shortcoming here, as we lacked a way to see clearly how they would interact and it led to the manipulators being somewhat prone to jamming.
Prototypes that did not succeed and why:
- Tube Ejector: We considered using spinning flywheels to eject the tubes into the totes. We even prototyped it, making a high-velocity tube launcher. This was a viable option, but we decided that it would be too difficult to control.
- Stepped box: Early on we attempted a passive tube alignment system, using multiple steps. The hope was that gravity and jostling would cause the tubes to fall down the steps aligning themselves. This didn’t work well at all. The tubes had a tendency to get stuck on the walls, other tubes, the steps, and anything else possible.
- Inside the bumper intake: Had trouble intaking tubes at non-ideal angles, and with tubes having to pass through the bumpers to the compliant wheels, many tubes would be knocked off angle by the robot.
- Roller claw: This one also had trouble with misaligned tubes. Depending on our design it also would have been subject to the bumper knocking the tubes out of alignment similar to the inside the bumper intake.
CAD Process:
We used master sketches in Solidworks to create a complete and easy to edit model of our robot. We also split into two groups led by our experienced CAD members to divide the work into more manageable chunks.

Above: Our intake master sketch
Major takeaways:
While master sketching is a pretty common practice in CAD across different software, we definitely recommend it to any team who doesn’t already do it—it really makes a world of difference (This is a great video to get started). In the future with master sketching, we would want to divide the master sketches into more layers for easier editability and fewer errors within sketches when changing dimensions. Going forward, we’ll also definitely want to implement some sort of “crayola CAD” to decide on packaging earlier and avoid as many conflicts later on when combining the work of our two groups. Similarly, doing a crayola CAD would have forced us to nail down an indexer concept sooner, which would have made the CAD process smoother than it was, having to design around a big unknown subsystem.
Learning with our Shapeoko 3 XL
For those with a similar machine who are having struggles, what we learned throughout bunnybots may be very useful. We started off using ⅛” 2 flute and ¼” 3 flute end mills from Carbide 3d for aluminum, but they were not very successful. We used the ¼” bit for slotting and roughing to get faster material removal rates, but needed to do tool changes after making our smaller bolt holes with the ⅛”. The 3 flute bit would frequently get clogged and run into chip welding even at slow feeds with a low DOC, leading to a not-so-fun end to the run and terrible reliability. Manually clearing chips with a brush did help some, but this didn’t feel at all like a sustainable long-term solution. Upgrading to a 4 mm single flute end mill made a world of difference. We also started using an electric duster for chip clearing with air blast which isn’t perfect, but we already had it. These two things combined are not exactly revolutionary in the world of CNC routers for FRC, but especially on a lower-end desktop machine like ours, don’t underestimate the difference they can make in reliability and speed. We still got the new equipment pretty recently so we’re still testing how fast we can get with it, but for anyone with a similar machine feel free to reach out and we’ll let you know our feeds and speeds as soon as we figure them out.
TL;DR: Use single flute end mills and air blast, they completely transform a desktop class CNC router.
Intake

This was the first time that any current team members had done robot pneumatics. We broke our team’s usual rule of using pneumatics on multiple subsystems by only having a pneumatic over the bumper intake, but it ended up being a good way to learn about pneumatics because the system was fairly simple. We used Festos instead of CKDs because we had more of them (so we had spares) and it was easier for us to change them in and out of manual and software mode. We found that bubble testing was a very good way to locate leaks in the system. When we did this we found that one of the fittings on the air tanks was loose and was the sole cause of a large pressure leak. Because the game piece this year was 4.5” diameter 11” long tubes, we decided on a maximum width four bar over the bumper intake with 2” and 4” diameter compliant wheels driven by one Neo motor and a passive kicker bar. We had one piston on each side of the intake with a ball joint on the end to hopefully reduce piston bending if the intake got hit while the pistons were extended (while the intake was retracted). This design wasn’t as troublesome as some of us were worried it would be (we hadn’t built an over bumper intake before or done robot pneumatics). We only put spacers between the larger compliant wheels with the plastic hex hubs, but not between the smaller compliant wheels that were hex bore. This meant that after a few matches or intense testing we had to push the smaller compliant wheels back to appropriate spacing or else tubes would start to get jammed between the bars.
Indexer(s)
This photo shows the motor mount on the side of the indexer, and the belt path from the motor to the shaft below it. This also shows the churros that we 3D printed spacers for in order to use them as standoffs to a polycarb plate that we used for vectoring the tubes into the indexer.

This photo shows how our indexer feeds into our outtake box. We used orange polyurethane belting (on crowned pulleys) that we “welded” into loops using a heat gun to melt 2” of overlap of the ends of the belting together. 

The picture above shows the lowest shaft on our over bumper intake while the intake is retracted. We used 4” diameter compliant wheels of different durometers, and they did a very good job of intaking the tubes even though the game pieces had very low coefficients of friction.
We have a two part indexer, one that was stationary, the other mounted on the elevator. Both are polyurethane flat belting on top, with polycarb bottom and sides. In our prototyping we found a maximum angle that we could mount the first indexer walls at to funnel the tubes into a thinner second stage without them twisting out of alignment. Also, during our prototyping phase we realized that we could use the tubes’ low coefficient of friction to our advantage. By limiting the amount of compression that the belts put on the tubes they would spin in place when pressed against a hard stop. This did two things: it allowed us to store tubes while the second part of the indexer was still running, and it would also correct for any misalignment in the tubes. We did still have numerous issues with misaligned tubes that we would have to eject, but with more tuning time we may have been able to minimize the number and effect of these jams. We had initial problems with the transfer between the two indexers because there was a polycarb lip that was stopping them from moving smoothly. Once we removed that the tubes had no trouble at all.
Takeaways:
Flat polyurethane belting continues to impress. With unfamiliar game pieces such as the tubes, more prototyping time is very useful in figuring out how the game piece will react in surprising ways.
Bunny Claw
Some of you may have noticed that there is not a bunny claw on our robot. We originally planned to have a separate bunny manipulator on our robot, but ran out of time. We were down to the wire to get the robot finished mechanically, much less give software an adequate amount of testing time. Additionally, we designed our tube path in such a way that it took up most of the horizontal area of the robot, making the packaging of a separate bunny claw very tricky. We were able to secure a 5.5” spherical bunny that worked well in our tube path. The only downside was that we couldn’t index both tubes and a bunny at the same time without a high probability of jamming. Usually that was not a huge issue, but during eliminations when we were under heavy defense for the duration of the match, every cycle was precious. That meant to score our bunny, we had to sacrifice almost an entire tube cycle. If we had a separate mechanism that wouldn’t have been as large of an issue.
Takeaways:
We need to manage our building time better, and prioritize what we need to complete. This includes also having more realistic goals during designing, and also adapting as our schedule changes throughout the build season.
Swerve
This was our first ever competition using swerve. We decided to purchase Swerve Drive Specialities Mk4i modules last spring, and although we had gotten them driving over the summer we hadn’t tested them in a rigorous way. We were using Falcon 500 drive motors and Neo turning motors. The robot was finished mechanically and electrically a week before BunnyBots, and while our software team had already programmed several subsystems and drive code, there was still a lot of tuning to be done, especially when different mechanisms needed tuning and repairs. This only gave our handful of drivers about five minutes of total drive practice each (they all rocked it at the competition though). Our main challenge was with machining the frame. We did not have any hole patterned tube in stock, so we had to machine it ourselves. We took 30” pieces of 2”x1” ⅛” wall tube and with our manual mill put the 8-32 mounting holes for the modules as well as the 10-32 holes for the rest of the subsystem mounts. This worked well, but took a good four hours to machine all the holes. Overall we are very happy with how the modules performed, and how easy it was to set up the frame mechanically.
Takeaways:
We cannot recommend SDS modules highly enough. Zero issues so far, we are very satisfied customers. Machining frame tube takes WAY too long, so we’re planning on purchasing hole patterned tube for the FRC season. We have awesome drivers!
Elevator

Building an elevator from scratch was an ambitious goal. Our last experience with an elevator was 2019, and we had no current members with any experience building elevators. We decided to build a two-stage bearing capture design, modeled after the West Coast Products GreyT V2 elevator. However we made a few small changes to the design to fit our specific needs, including changing motor mounting and moving the second stage rigging to allow passthrough.
Since we were not using hole patterned tube, we had to spend a lot of time just drilling out mounting holes on our drill press. We then had to spend a lot of time squaring up each elevator stage, because surprisingly we’re not perfect at locating holes. As mentioned previously we are going to use hole patterned tube, so this should be a non-issue going forward.
Due to our previously mentioned indexer design we needed to maximize the width of the elevator carriage because the carriage width would dictate our intake width. To make the elevator as wide as possible, we mounted the drive motor parallel to the bottom shaft spaced out on a ⅛” aluminum plate attached to the base of the elevator (remember that, it WILL come up again). We used a Neo in a 50:1 planetary gearbox which drove the lower elevator shaft via a short chain run. The motor was mounted from the bottom of the gearbox by two bolts spaced up from the plate, as well as supported under the motor. This caused several problems. Remember that ⅛” sheet aluminum. Well, it turns out that the force needed to lift an elevator is pretty big. That force tried to pull the motor output shaft and the lower elevator shaft closer. It succeeded, and bent the aluminum mounting plate.
Over the course of three days we tried different solutions to try and fix this problem. We began with the lazy fix, securing another piece of sheet ⅛” aluminum between the drivetrain and the motor mount plate. This worked, but since it wasn’t attached at the end of the plate, it only stopped part of the bending. We then attempted to install a single plate with two bearings spaced at the correct shaft distance at the end of the motor output. The intent of this was to keep the unsupported end of the output from being pulled closer to the lower shaft. Technically this did what it was supposed to.
However we were faced with multiple more issues: the lower shaft was bending when the motor was being driven, and we still had not addressed the root issue of the bending motor mount plate. To get it to finally work, we implemented multiple fixes simultaneously. We bolted a second two-bearing plate to the output side of the gearbox in an attempt to keep the shaft from bending in the area with the chain run. We also replaced the motor mount plate with an equivalent piece of ⅛” aluminum angle that both keeps the plate from bending, and twisting because the angle was braced up against the drivetrain. Although this held through the competition we noticed that one of the bearings was still popping out, and may have even broken. We have yet to do a full inspection on our robot after returning from the competition, but competition seems to have taken a toll on this motor mount. This is definitely something we’ll have to keep in mind if we design an elevator for the 2023 FRC season.

We had issues with dyneema tensioning (or the lack thereof), although none of them seemed to be complete showstoppers. We had a clamping system that was meant for tensioning, but it slipped frequently and was inconvenient to tension. A system using a ratchet like on the Thriftybot elevator or Greyt elevator would be slightly more complicated but more effective.
We use rather hefty chain, #35 to be exact. I don’t know why we’ve accumulated so many #35 sprockets and chain parts, but we have, so that’s what we used. We used two AndyMark in-line chain tensioners to make sure we didn’t have any chain skipping issues. Due to other issues our elevator wasn’t perfectly square, so on one side the chain was not tensioned even with the tensioner trying its very best. This wasn’t causing issues until we got a tube stuck crossways in the elevator and tried to lift. As you can guess, that didn’t go very well. The chain made an awful skipping noise. The chain was less tensioned after this incident so we decided to remove a link and retention from there. Unfortunately when attempting to loosen the chain tensioner, it sheared. We suspect that the internals on the tensioner had been damaged during the chain skipping incident. We also neglected to buy any spares, so we were two days out from competition and an irreplaceable part was broken. We were luckily able to just reattach the chain without the tensioner, and although it was quite slack it worked for the duration of the competition.
One last note. We spent a lot of time disassembling and reassembling the elevator to replace bolt heads that were interfering in the elevator’s travel. Try not to let that be you. Use low profile bolts, rivets, or just be very careful to leave plenty of clearance.
Takeaways:
Unfortunately Newton’s 3rd law still applies, no matter how much we wish it didn’t. Cantilevering a motor is a recipe for disaster, and we need to approach our motor mounting solutions for elevators cautiously. This especially applies if we need to climb via our elevator. ALWAYS have spares. No matter how bulletproof you think a part is, if you don’t have a spare, it is the one thing that will break. Make sure that in CAD none of the bolt heads or nuts will interfere with elevator movement. Also make sure that you have all of the low profile bolts that you think you do before designing around them. Use hole patterned tube, or be able to machine it quickly in house. It will save you tons of time and headaches.
Mechanical Notes
-
Talk to CAD! Make sure everyone who is working on a project knows the correct dimensions and put those dimensions on a Google Doc in the team drive so it can be accessed by anyone. This also prevents mistakes due to misread handwriting and losing checklists of stock dimensions.
-
DO NOT skimp on buying inexpensive chain tensioners and buy spares. If your chain tensioner breaks, you need to be able to replace it quickly, as well, so put either half links or master links. Also, they only go so tight. Don’t try to over-tighten one, it’ll break. Snap right in two, and then you’re left with untensioned chain and disappointment.
-
Elevators are precise and finicky. Stock up on low-profile bolts, because anything that could run into anything else is a problem. Try to give every bolt head and protrusion significant clearance from any moving part- more for wires.
-
Bearings are finicky as well. If your elevator relies on bearings sliding smoothly against something, you need to make sure that your placement is precise, as if the bearings are too close together or too far apart, your elevator won’t quite work right.
-
Elevators like to be square. They really do. Try to make things square as you build them- we used a system where we clamped each corner to something square in two dimensions, because then as we build it it’s solid and square. And don’t forget to check the alignment of your tools! We had to re-square parts of our elevator because our drill press table was slightly misaligned and drilled slightly diagonally.
-
Remember to include junior members. There should always be enough work for everybody if you’ve planned well, so make sure to distribute labor so not every task relies on one thing that takes weeks. Try to make it so several tasks can happen at the same time, so you can go faster and don’t spend half of your build season waiting on another subteam or group.
Electrical
As far as the general layout for the electrical components go, our Bunnybots robot electrical board strongly resembled those that we had made in past competitions. Some key changes we made were wiring the Falcons, (which if anything was much simpler than the CIMs that we typically used on the drive train), and incorporating some pneumatics components that communicate with the rest of the electrical components. One other change we made was switching almost entirely to brushless motors. We used two brushed motors, a window motor, and a mini cim on the elevator outtake. Everything else was NEOs or Falcons. This meant that we ended up using Spark Max motor controllers exclusively. In the past, we had tried to incorporate Talons wherever possible for budget reasons, but given the quantity of Sparks we had from the previous season as well as new ones we purchased, we had a sufficient quantity to go all in on the Bunnybots robot. This helps because when only using Sparks, the CAN can be routed strictly from device to device without the need of canbuses which could take up space on the electrical board.
Speaking of space on the electrical board, due to some poor communication with other subteams, we ended up with a sub-optimal area to work with mounting components. We ended up using all but a few slots on our PDB, which made for some interesting motor controller placements going side by side, not even leaving enough room for zip ties, solely being held down by VHB tape. Additionally, we had to figure out where we could mount some pneumatic components which each presented their own difficulties. Whether it was the compressor needing to be completely isolated to avoid being near temperature sensitive parts of the robot, or needing a pressure gauge to be visible from a reasonable angle, we were left with a slim number of mounting possibilities just to fit the necessities around the PDB and Rio.
By far though, the largest problem we encountered was routing wires to the motors and sensors on the elevator. While we ended up with a functional robot, our solution was by no means a good one. We ran a strip of energy chain that curled with the elevator. We were only able to fit a few AWG12 motor cables through the actual housing so we ended up zip tying the other 2 AWG12 cables and a few AWG18 sensor cables to the outside of it. While this allowed for relatively uniform movement when the lift went up and down, it presented a very loose loop near the edge of our robot that could be potentially very prone to snagging as well as maybe pushing some frame perimeter dimensions.
As far as the components on the elevator go, we made an attempt to mount as few components to it as possible, but if we had to mount even one motor, adding other motors or sensors wouldn’t change the fact that there were wires that needed to be routed. In the end, there was a mini cim and a window motor, multiple cameras, as well as 2 limit switches on the elevator mechanisms that would all have to be run through the energy chain.
Software
For Software we used plain WPILib. We had experimented with swerve over the summer and had some swerve code built up from that. Currently we are still working on auto for swerve as the WPILib trajectory library is built for mostly tank drive. They do have support for swerve, but it is not very good, especially handling rotations can be annoying. We decided to experiment more with the robot code. So what a subsystem does and what a command does is not clear in the code currently. Currently, some subsystems manage the motors and only provide higher level control such as the intake, while subsystems like the lift provide low level control. I personally am leaning towards subsystems having most of the loops and lower level motor control.
We were hoping to use computer vision with apriltags for bunnybots, however we only had a few hours to test the robot so there wasn’t enough time. There is actually still the vision code in the code base, but it is unused. We had a really hard time getting vision to reliably connect. We only have a PI 3b (I think) due to the PI shortage and it seemed to have a hard time connecting to the roborio when using WPILibPi (it would usually fix after a restart of the vision code) and Photonvision only seemed to work with one camera. I was planning on fixing the WPILibPi connection problems by having it restart the code until the main robot code changed a NetworkTable value on the vision table. I never got to try that change.
We also added a whole system for tunable constants (you can check the code for details) that would allow you to change robot constants from shuffleboard for testing (not permanently). To my knowledge it worked, but it was never used because not a lot of tuning happened. Software only had a couple hours of time with the robot so the code is pretty messy. There wasn’t enough time to actually make the encoder values match any real world unit system (we always use metric software) so there are a lot of numbers that don’t really have any real world meaning. The PID values are more or less random and all the feedforward and PID values from Sysid’s tuning were doubled because those numbers were just tuned for the drivetrain which weighed less. Furthermore, I think the x and y coordinates are swapped. The auto also only really worked in testing so it had to be changed to do less in the actual competition.
The auto (actually hybrid, but we treated it as auto) for bunnybots was only ten seconds, meaning the robot had to move fast. Testing the auto also almost took up the entire testing room. When testing, the robot drove forward then outputted one tube in the inner zone, then drove backwards while putting the second tube into the outer zone. It then raised the lift, drove forward and outputted a tube into the top zone.

On the real field it wasn’t able to properly drive the right distance and we weren’t able to easily test on the real field, so the top zone part was removed out of fear that the flap was hitting the table.
Software Notes and Problems
- Brushed motors don’t work without disabling Hall Encoder for SparkMaxes.
- Indexers had to run at high speeds because speeds less than about 80% would make the tubes get stuck. This caused a lot of battery drain. Solution: Add encoders to the motors and run PIDF making them only run at 80% when needed.
- Robot rotated when there was no joystick input, but only for one joystick. Solution: The deadband was decreased for more precise movement in auto testing, but Ks in the feedforward were not tuned at all causing anything above 0.01 from the joystick to move it significantly, so increasing the deadband solved it.
And that’s our recap of our BunnyBots season! Thank you to the Flaming Chickens for hosting the competition, and to everyone for making it such a fun place to be!