Team 3467 2023 Build Blog

Interesting to hear you get away with one coat. I figured it was more with how consistent your colors are.

We started with one coat on the first bellypan and it looked okay. We started doing double coats in black to make sure we had good coverage and keep things consistent if different people were spraying. After that it was doubles all around.

Yellow, we found the toughest and needed 3-4 coats before they got a nice finish and coverage. Not surprised with it being a light color. Yellow did have some issues in curing with them picking up imprints easily with the paint being soft even four days after coating. Up close you can see it, but we don’t notice it now.

1 Like

Our robot is matte black, similar to your folks one. I thought I would like it, until someone pointed out we look like the Raiders… :grinning:



Black and yellow are two of the worst-covering paint colors, so multiple coats may be inevitable. I’ve tried a bunch of different brands/types of spray paint over the years, and I’ve found that Rustoleum Painter’s Touch 2x does the best job of single-coat coverage. Not sure if it’s the right choice for yellow, but the black I’ve used works well.

You may find that a black primer for black parts and a white primer for yellow parts lets you get things done in fewer total coats. EZ Coat was suggested by a buddy of mine who used to do autobody work professionally.

We spray in the automotive paint booth at our tech center, which is kept pretty warm (over 70F usually) to accelerate paint curing. You can use a heat gun to warm up the parts and really cure the paint quickly if a warmer space isn’t an option. Aforementioned buddy kept his painting area at 75-85F to be able to move more jobs through the shop.

Off on a bit of a tangent here… oh well.


This is a good tangent (hopefully) for everyone to learn from. Our decision to spray paint was heavily based on pulling in as much info as we could and looking to other teams like 95. The more out there - the better for all teams.

Everyone looks at anodized or powder coated robots and hopes they had a company willing to coat parts for free quickly. People don’t talk about painting enough: who’s doing it, what to use, prep work, etc.

We did our own powder coat in 2020 using an oven in a student’s garage with a few large parts done by a sponsor. Too time consuming of a process and had to be done offsite. This has been easy, quick, cheap, and lets us make quick changes on the bot later we can color match.

We also used Rustoleum Painters Touch 2x.

We do not have a paint booth so we just laid parts out in the shop on covered boards, sprayed, and then opened the doors for ventilation. Not the best, but we surprisingly didn’t end up with much or any junk getting blown into parts from the breeze. That did introduce some temperature fluctuations so we made sure before doing the next coat to close the door and get the temp up.


Let’s talk about Slop

We built our arm joints with a goal of making it as rigid as possible. We used sprockets bolted through the arm, through MAXspline plates, and through shaft collars on Rev MAXSpline as a live shaft rotating about ¾” tube deadaxle with tube nuts for our shoulder joint.

Despite a lot of effort put into the joints, we still have a bit of slop in the arm.

Where is it coming from?

The running theory from testing is that most of our slop is coming from the chains, and some is coming from our gearbox setup (MAXPlanetary with a rounded hex shaft output). Additionally, since the encoder we’re using to measure arm position is geared off the lower rounded hex shaft, the encoder doesn’t “see” the slop, so it’s difficult to account for programmatically.

What can we do about it?

We have a few steps we can take:

  • Remove more slop from the lower gearbox by
    • Shimming the hex bore on the lower sprockets
    • Switching to non-rounded hex shaft
  • Set up our encoders so they “see” more of the slop and can account for it when setting our arm position

We decided to explore other encoder mounting positions and methods and came up with these:

Bottom Joint

To avoid disassembling the arm, and to reduce slop in the fit, we made a clamping gear that clamps onto the shaft and is held together with a bolt and nut on each side. This setup is positioned after the slop from the chain, and should provide better feedback that accounts for the chain slop.

Top joint:

For the top joint, we’re using a sectioned out spur gear so it can fit over the top joint’s boxtube. The large gear is necessary so the center point will be aligned with the joint’s axis of rotation.


This method does have a trade-off: the elbow joint can’t swing “backwards”. Backwards pickup/scoring was never in our game plan, especially for early-season play, and none of the forward positions of the arm require bending in that direction.


We put some hex-shaft inside our 3/4" ‘dead tube’ using a short length of 1/2" copper pipe as a bushing. It’s pretty perfect. The copper tubing was a press-fit inside the 3/4" tube and the non-rounded hex shaft appears to be also a perfect fit. We pinned the hex shaft to the MaxSpline with a cotter pin. Through-bore encoder is bolted to the outside of our MaxTube.


Do you have a picture or a CAD screenshot of this? Sounds really interesting, but can’t quite visualize it.


Let’s see if I can do this with my phone…


Not to derail this awesome conversation but what do you guys use for cad?

There is a link to the teams onshape model in this thread.

1 Like



I think all you’ll need to do is flip-flop one chain tensioner on each of the dual runs you have. With the ‘left’ chain runs on the ‘back’ of the joint their tensioners will work against the tensioners on the ‘right’ side to lock up all of the slop. Should take all of 10 minutes to try out: unbolt tensioner, loop chain so the tensioner is on the other side, reconnect tensioner.


missed it! thanks!

1 Like

Software Update 3: Saying Goodbye to the Alpha Robot: Hello Yellow :yellow_square:

It’s been quiet here on the blog from the software side for a bit, so we figured it’s time to share some progress!

The above videos show the silver alpha robot in its final form, running with its pneumatic wrist, “beta” version of the arm control software, and “spinny no pinchy” claw (see above).

When we built the alpha bot, its primary goal was to give the software team adequate time to lay a solid foundation for arm control that wasn’t rushed or hacked together, while also providing valuable insights for the design teams working on updates to the arm and intakes. Additionally, we wanted to address even the smallest of control irregularities or odd behaviors from the onset, to leave as little tech debt as possible for us to address later in the season.

In the videos above, the arm moves smoothly between its setpoints and holds position well, so we can say with confidence that the alpha robot has done its job. Let’s dive into the software powering it!

Arm Control Software

Our initial instincts were to use Motion Magic with the CTRE api, but since our REV through bore encoders are wired to the RoboRIO, not to the TalonFXes on each Falcon 500 powering both joints, we didn’t find a good software solution for configuring the sensors to the talon. It was at this point we pivoted to on-RIO control.

We started with two PIDControllers, one for each joint, tuning setpoints and gains for each joint independently. We found this to have precise enough control, but the arm wasn’t moving very smoothly, and so we knew we needed to use trapezoidal motion control. After a few days of struggling through the semantics of the api, we got ProfiledPIDController implemented with each joint of the arm having its own controller. Note that it’s necessary to call reset() on your ProfiledPIDControllers upon enabling the robot or switching back to PID after using an open loop control mode - this had us scratching our heads till we discovered it! After tuning the gains and trapezoidal constants, we landed on a solid implementation but lacked the final piece - feed forwards.

We noticed that as the arm approached horizontal angles, it would struggle to reach the setpoint until the integral term would build up after a few seconds of waiting, and then seem to slowly oscillate. This was suboptimal to us and we knew we needed a feedforward solution. WPILib offers ArmFeedforward which works well for single jointed arms, however we realized that for a double jointed arm, the dynamics are significantly more complex.

We then brought in 6328’s Double Jointed Arm Feedforward class, which is an implementation of the dynamics model published in an excellent paper by @rafi of Team 449. After some tweaking to make sure all of our directions and “zero points” were correct, this ended up being the final piece of the puzzle we needed, stabilizing the arm at steady-state positions and significantly reducing slow oscillations.

Cardinal Direction Drive Control

One thing we realized from the game reveal was the orthogonality of the scoring and pickup locations, that is to say, they all lie at 90 degree angles to one another. This presents a great use case for Cardinal Direction Control - shoutout Teams 111 & 6329 for inspiration - wherein the A B X Y buttons on the driver’s controller correspond to 90 degree angle increments for the drivebase heading. This also still allows translational control as normal, so this can aid in quick alignment to scoring or pickup locations.

Architecturally, this is a simple PIDController closing the loop on the gyro, which takes over control of the swerve drive’s theta value when a button is held. A neat trick is to enableContinuousInput() and use inputModulus() in the WPILib MathUtil library on your gyro value, so that your drivebase never spins the long way around, and always takes the shortest path to a given heading.

Goodbye Alpha!

Starting today, the software team will begin working on porting the code to the Gold robot, which is the first of two competition-spec robots the team will be building this year. The Gold robot is similar, but not identical, to the Alpha robot. The Gold robot for example has a Spinny + Pinchy claw, with a pneumatic release to make dropping cones much more smooth than the Spinny No Pinchy claw.

Once we feel confident with the performance of the Gold robot, we’ll dismantle the Alpha robot’s drivebase so its SDS Mk4i modules can be installed on the Black robot (the second competition robot currently undergoing assembly). The arm will stay together to serve as a pit display and test platform should it be needed. So in a few days we’ll say farewell to the Alpha robot, the one that started it all!



Keep up the great work guys!


Thanks John! Looking forward to seeing the 6329 machine. :slight_smile:

For those new to the thread and who would like a summary of our season posts so far, you can use the Summarize This Topic button at the bottom of the original post.


We and another team we know have both recently experienced failures with the tube nuts in our 3/4" Tube Axle for our arm joints.

Our setup has the tube nuts under considerable loads (cross-section below), so this isn’t a crazy failure - but has anyone experienced failures like this with tube nuts before? This is our first year using them so we’re curious if anyone has any tips and tricks.

Our tube nuts were from McMaster-Carr: McMaster-Carr

For now we’re swapping the tube axles for some solid 3/4" aluminum round stock tapped at each end. It’s about 3x the weight (0.3 lb vs 0.09 lb) but for now it’s not a big difference.


One solution is to cancel out the shear load using plate and only use the tube nuts for tension. That should keep the mass down while still providing rigidity