BIOBUZZ Robot Design Review
FTC 2026–27 BIOBUZZ · dual-intake robot · review of "intake assembly 2"

BIOBUZZ Robot Design Review

A dual-ended star-wheel intake on a goBILDA mecanum base, checked part by part from the 106 MB Onshape export (1,646 parts). Then a transfer and outtake designed to fit it, and a full code base tested in FTC SimBench Pro.

CAD exported 2026-10-18 01:39 UTCreviewed 2026-10-17code: IDK-WHAT-TEAM-IM-ON · Testing-code · d3476ff
Fix before buildingThe intake can't drive a ball upNo ramp sits under either roller chain. The lowest roller squeezes a NECTAR by 40%. The star wheels never touch a ball on the floor.
Fix in CADHalf the assembly is unmatedThe front intake is yawed 33°, bearings float 0.5 m away, the battery sits outside the frame, and ramps hang below the tiles.
CheckAbout 19 in long as drawnThe back intake and ramps stick out about 40 mm past an 18 in START box centred on the drivetrain.
Designed + codedColumn transfer, two-wheel shooterZero-spin shooter on one 6000 rpm motor. The shot sim gives a 97–99% hit rate from every scoring spot. The auto runs two cycles in sim.
01 · what the CAD file actually contains

CAD findings

The export holds a Full Robot sub-assembly (chassis, two intake copies, two ramp copies, traction and jamming wheels) plus a newer top-level intake (two intake wheel assemblies, a ramp assembly, side arms, a floor plate). Field elements (a POLLEN and a blue NECTAR) are dropped in loose. Every part below was placed with its own occurrence transform and meshed with OpenCascade.

Top view of the robot CAD with the yawed front intake in red, a duplicate intake in orange, the battery in blue outside the frame, and an 18 inch start box drawn around the drivetrain centre
Top view. Grey is what lines up. Red is the yawed front intake and parts floating far away. Orange is the second intake copy inside "Full Robot". Purple is the Full Robot ramp copies. Blue is the battery. The dashed box is the 18 in START cube centred on the drivetrain.
SeverityFindingWhat to do
FixThe front top-level intake wheel assembly is rotated about 33° about vertical. Its 312 mm shaft runs diagonally and pokes past the frame side to x = 218 mm. The back copy of the same sub-assembly is square. Internally the front copy is consistent (bearings sit on its shafts), so the whole sub-assembly is unmated rather than broken.Add a fastened mate to the frame, then mirror the back intake's mates.
FixBoth Full Robot › ramp assembly copies hang 70–85 mm below the tile surface. One ramp attachment sits outside the frame at x = −275 mm.Mate or delete. The top-level ramp assembly is the placed one.
FixThere are two intakes in the file: the top-level pair and two more inside Full Robot. They overlap the same space, so mass (11.6 kg as drawn) and interference checks are both wrong until one set goes.Suppress the old Full Robot intake.
CheckThe 12 V battery sits 140 mm outside the left side plate. About a dozen bearings and screws from the intake sub-assemblies float about 0.5 m away.Mate them. The battery placement also moves the centre of gravity.
CheckThe back intake and its ramp reach 250 mm behind the drivetrain centre, and the front ramps 230 mm ahead. That is about 485 mm (19.1 in) overall against a 457 mm START limit. The side arms and plate reach 96 mm past the front: fine as a deployed expansion (about 23.4 in in total, under the 24 in limit), but they must fold for START.Trim 30 mm or fold one intake. Sizing-box check before inspection.
OKThe odometry pods mount at the same height. One is drawn sprung down and one up, which is fine for spring-loaded 4-bar pods. Measured offsets from the drivetrain centre: forward pod 3.9 mm right of centre, strafe pod 39.9 mm behind centre. These are set in Constants.java.Confirm the encoder directions on the bench.
OKThe traction + jamming wheels look like a servo-and-rack brake that drops small wheels onto the tiles. The code drives them as leftJam/rightJam with up and down positions.Make sure nothing that touches the tiles can damage them.
Side view of the robot with the tile surface marked and the Full Robot ramp assemblies drawn below the floor in purple
Side view. The black line is the tile surface, set from the mecanum wheel contact. The purple ramp copies sit below it.
02 · the problem that matters on the field

Intake geometry

On the correctly placed back intake, three roller rows climb at 38° toward the robot centre: the lowest at 83 mm, then 136 mm, then 184 mm above the tiles. The motor (a goBILDA 1150 rpm) sits on top. The only ramp parts are a short plate near the centre and the floor plate at 82 mm.

Section through the back intake showing the three roller rows, the lowest roller 55 millimetres above the tiles, and a POLLEN and a NECTAR drawn on the floor under it overlapping the roller
Section through the back intake rollers. A 71 mm POLLEN under the lowest roller is squeezed 16 mm (23%), and a 92 mm NECTAR 37 mm (40%). The six-arm star wheels start 100 mm up and never reach a ball on the floor.

Why this fails, and the fix

A roller only lifts a ball if something under the ball pushes back. With no ramp, the lowest roller can at best roll a POLLEN along the tiles. A NECTAR at 40% squeeze stalls the 1150 rpm motor or gets shoved away. One fixed gap can't serve both sizes either: a gap set for 15% squeeze on NECTAR leaves POLLEN untouched, and the reverse crushes NECTAR. Teams hit the same wall in DECODE and BIOBUZZ prototypes; 12737 reported their fixed two-wheel prototype sending the two sizes to different heights.

  1. Add a ramp under each roller chain, parallel to it (38°). Start it at 4–6 mm off the tiles with a chamfered lip so a ball touching the wall still rides up.
  2. Make the ramp float, not the rollers. Hinge it at the centre end and spring it up toward the rollers. Set it 61 mm below the roller tips at rest: 10 mm squeeze on POLLEN, and NECTAR pushes it down 21 mm. Use a stop so it never passes 25 mm of travel.
  3. Drop the lowest roller to about 45 mm off the tiles and make it compliant: surgical-tubing flaps or a 72 mm Gecko instead of the rigid hub. It grabs, then hands off to the star wheels.
  4. Mount the colour sensor at the first roller, aimed sideways at the ball centre line, 15–30 mm from the ball. That is where the ball slows, so the code gets two clean reads before it commits.
  5. Keep walls solid where a ball rubs. The 11 mm POLLEN holes and 16 mm NECTAR holes catch on standoffs and slots, the same snag Leviathan fixed in DECODE by switching to solid walls.

CAD check, 2026-10-18. Modelling these parts against the robot showed two things to decide before cutting. First, the ramp line drawn in the schematic below, (±255, 6) to (±70, 150) mm, sits only 9 mm under the rollers. That leaves no room for a ball. A ramp with the 61 mm gap runs (±170, 6) to (±70, 84) mm; otherwise the roller chain has to move about 52 mm up. Second, below 64.5° pitch the shooter's top wheel reaches the staged ball. Either limit pitch to 65–87° or lower the stopper to about z 310 mm. The REV power switch also sits inside the sprung roller stack and needs to move.

03 · designed for this robot

Transfer and outtake

Both intakes deliver to the floor plate between the intake towers. That bay is 116 mm long front-to-back and 240 mm wide, so the transfer goes straight up through it. The shooter sits on top and fires over the front intake. Aiming is by the chassis (heading lock), not a turret, which keeps the build inside 8 motors and leaves 4 servos spare.

Column
Single file, 82 → 300 mm. Two stacks of 72 mm Gecko (30A) rollers on fore-aft axles, either side of the ball. One stack is fixed; the other is on a sprung swing plate with 25 mm of travel.
Drive
goBILDA 435 rpm (13.7:1) gives 1.6 m/s at the roller surface. Belted to both stacks.
Holds
2–3 in the column + 1 staged under the stopper. The code never lets the total pass 4 (G407).
Shooter
A bottom shaft with two 96 mm Hogback (50A) wheels and a goBILDA steel flywheel. A top 72 mm Hogback on a sprung arm, belted 4:3 so both surfaces match: zero spin.
Motor
goBILDA 6000 rpm, 2:1 HTD belt to the bottom shaft. About 1,120–1,300 wheel rpm in use, 40% of the motor's top speed.
Pitch
The pod pivots on the 96 mm wheel's shaft, so the motor belt never changes length. 60–87°, driven by a goBILDA 2000-series torque servo through 3:1 gears. The nip moves about 35 mm over that range, and a curved guide from the column covers it.
Exit
The nip sits 14.4–15.9 in above the tiles, depending on pitch. The shot map was built at 16 in, and the one measured efficiency number absorbs the difference. At START the pod sits at 87° so the rear wheel stays under 18 in.
Gate
A stopper servo flap under the nip. It opens to feed one ball and closes when the shot is detected.
Sensing
2 × REV Color Sensor V3 (intake mouths), 2 × 3 mm IR break beams (column entry, top), Pinpoint, Limelight 3A facing front.
Mass
About +1.6 kg (column 0.7, shooter 0.9). Pedro's mass is set to 12.5 kg.

Why this shape

Zero spin. Escape Velocity (14343) measured a 44% bounce-out rate from backspin with a DECODE-style fixed hood. A matched-speed two-wheel shooter sends the ball in without spin. Changing one pulley adds a little topspin if testing shows the CELL still spits balls out.

Both sizes in one shooter. The top wheel is sprung, so POLLEN (71 mm) gets about 10 mm of squeeze and NECTAR lifts the arm 21 mm. No sorting and no hood change between balls; the code only nudges pitch and speed per ball type.

Motor budget. 4 drive + 2 intake + 1 column + 1 flywheel = 8 motors. Servos: pitch, stopper and the 2 jamming-wheel servos = 4 of 8.

04 · built with biobuzz-shot-sim

Shot map

Pitch and exit speed for every combination of range (robot centre to the up-CELL mouth centroid) and bearing (how far off the CELL's facing direction the robot stands). Built with the shot sim for a two-wheel, zero-spin shooter at a 16 in exit. Hit rates are 97–99% from 20 to 60 in at bearings up to 60°. Side shots need up to 8° more pitch than straight-on shots at the same range, which is why the table is two-dimensional.

POLLEN pitch° / speed m/s12.5 in15 in20 in25 in30 in35 in40 in45 in50 in55 in60 in
bearing 0°83.5° · 5.0281.8° · 5.0278.0° · 4.9575.0° · 4.9772.0° · 5.0569.0° · 5.1267.0° · 5.2065.0° · 5.30–––
bearing 20°83.3° · 5.0081.5° · 4.9778.0° · 4.9575.0° · 4.9772.0° · 5.0270.0° · 5.1068.0° · 5.2065.0° · 5.30–––
bearing 40°84.3° · 5.1282.0° · 5.0079.0° · 4.9776.0° · 4.9774.0° · 5.0570.0° · 5.1068.0° · 5.1766.0° · 5.2864.0° · 5.3861.0° · 5.49–
bearing 60°86.0° · 5.8082.8° · 5.2581.0° · 5.1078.0° · 5.0575.0° · 5.0572.0° · 5.1069.0° · 5.1767.0° · 5.2565.0° · 5.3665.0° · 5.46–
bearing 75°87.0° · 6.4387.0° · 6.4383.3° · 5.3880.0° · 5.1776.0° · 5.1773.0° · 5.1771.0° · 5.2568.3° · 5.3066.3° · 5.41––

The wheel rpm comes from one measured number: EXIT_EFFICIENCY (0.90 assumed). Tune it with the Shooter Tuner OpMode at two ranges and the whole table follows. NECTAR has its own table in ShotTable.java.

05 · in pedroPathing/ on Testing-code

The code

Pedro Pathing 2.1.2 and FTC SDK 11.1.0, matching your project. It compiles cleanly. Four OpModes go on the Driver Hub: BIOBUZZ TeleOp, BIOBUZZ Auto, Shooter Tuner and Hardware Check. Subsystems live in pedroPathing/robot/.

Problem teams hitWhat this code does
Flywheel sags after a shot; the "ready" light flickersFeedforward (kS + kV) plus PI, scaled by battery voltage, with full power while more than 12% slow. Ready means within 3% for 80 ms, and it only drops out past 6%.
Two balls fed at onceThe column pushes only until the staged ball clears the top beam, then stops. The stopper closes as soon as the wheel's speed dip (4.5%) confirms the shot.
Controlling opponent NECTAR (G408)A colour sensor at each mouth sorts every arrival, even balls back to back. The intake runs slow until a ball is classified, then spits out the wrong NECTAR. The driver feels one rumble blip.
Holding a 5th element (G407)The inventory counts balls in the column plus balls on their way in. At 4 both intakes stop, and any new ball is pushed back out.
Both intakes feeding one merge pointWhichever intake takes a ball claims the merge for 650 ms. The other holds its ball at the mouth until the merge is free.
JamsOver 5.5 A for 180 ms backs that motor off for 220 ms, with a 500 ms cooldown. A column that can't stage a ball in 2 s stops and flags STUCK.
HIVE tags move, so localizing off them is wrongThe Limelight only answers which CELL is up: the highest tag your alliance can see, held for 250 ms. Position comes from Pinpoint. The operator can flip the CELL state on gamepad2 A.
Overfilling a CELL wastes ballsCounts grams banked in the up CELL and rumbles three times at 199 g, when the TIP is certain.
Shooting while movingAims at a virtual target: the mouth minus robot velocity × flight time, iterated 4 times. Blocked above 30 in/s.
Slow loopsManual bulk caching, motor writes skipped when nothing changed, current read at 10 Hz, colour sensors read only while intaking. Telemetry shows the loop time.
Wrong config name or a reversed motorHardware Check lists what's missing, jogs each motor and servo, and shows the colour sensors' hue and saturation with the ball they'd call.

Controls

InputDriver (gamepad 1)Operator (gamepad 2)
SticksLeft: drive (field centric, Y toggles). Right X: turn. Left-stick click: slow
TriggersRT intake · LT ejectRT intake · LT eject
BumpersRB hold: aim + fire everything · LB hold: aim + spin onlyRB fire
Face buttonsB jamming wheels · Y field/robot centricA flip HIVE state · B jamming wheels · X clear STUCK · Y reset CELL grams
D-pad↑↓ speed trim ±1% · ←→ pitch trim ±0.5°↑ add POLLEN · ← add own NECTAR · ↓ remove last
BackReset heading (robot facing away from you)

Auto INIT: X = blue, B = red; D-pad picks FULL, PRELOAD_AND_PARK or PRELOAD_ONLY. The robot starts with its back against the audience wall at x = −40 in. The end pose, HIVE state and held balls carry into TeleOp.

06 · run headless in FTC SimBench Pro

Sim results

SimBench Pro's Java VM could only drive Pedro in TeleOp, so it now follows Pedro 2.x paths (lines, curves, chains, heading interpolation, callbacks, hold point). Five new tests pass, plus the full suite (777). The real Auto and TeleOp files ran in it against a small robot model. The runs found four bugs, all fixed in the code: a 5 s wait before the first shot, an opponent NECTAR sneaking in behind another ball, a ball stranded at the mouth, and a second cycle that drove to the wrong side to shoot.

TimeFULL auto, red, partner banks 120 g in the far CELL
0.0–3.2 sTurns to 59°, spins up, fires 4 preloaded POLLEN (1.56, 2.10, 2.64, 3.18 s)
3.3–6.3 sWaits for TIP 1 (assumes it at 223.5 g if no camera sees the swing)
6.3–8.8 sSweeps the audience-side spill at y = −33 in: takes P, R, P and spits out a blue NECTAR
8.8–12.7 sDrives round the HIVE into the LOADING ZONE, fires 3 at the far CELL
12.8–17.8 sTIP 2, sweeps the far-side spill: takes R, R, P, spits out a blue NECTAR
17.8–22.0 sFires 3 from the audience pocket (the up CELL flipped back)
22.1–24.4 sParks in the LOADING ZONE with 5.6 s to spare

The sim robot is a kinematic stand-in. It proves the logic, timing and paths, not real traction, real ball contact or your real flywheel. The tuning steps below close that gap.

07 · in this order

Setup and tuning

  1. Configure the Driver Hub with these names: leftFront leftRear rightFront rightRear frontIntake backIntake column flywheel, servos pitch stopper leftJam rightJam, colour sensors frontColor backColor, digital columnIn columnTop, pinpoint, limelight.
  2. Run Hardware Check. Fix anything missing, check each motor's direction (flip the booleans in RobotConfig), and find the servo positions for PITCH_SERVO_AT_MIN/MAX, the stopper and the jamming wheels.
  3. Hold each ball at each colour sensor and copy the hue ranges into RobotConfig. The defaults are yellow 35–85°, blue 185–260°, red below 25° or above 330°, saturation at least 0.30.
  4. Run the Pedro tuners (localization test, forward/lateral velocity, zero-power deceleration, PIDF) and weigh the robot for Constants.mass.
  5. Shooter Tuner: place the robot at a measured 30 in and 50 in straight in front of the up CELL. In table mode, adjust EXIT_EFFICIENCY with the bumpers until shots land, and copy the number. Check kV and kS while you're there: power should sit near 0.42 at 1,100 tps.
  6. Limelight: AprilTag pipeline with Full 3D on, and set CAMERA_HEIGHT_IN and CAMERA_PITCH_DEG. Watch the "hive" telemetry line flip when you tip a HIVE by hand.
  7. Auto: set PARTNER_AUTO_G to what your partner banks in the far CELL (keep it 0 if unsure; the second cycle then waits for the camera).
08 · from the deep-research report

Research notes

Brogan M. Pratt teaches robotics at The American School of The Hague and coaches FTC 23014 (The Flying Dutchman) and 24090 (Trojan Robotics, 2026 Worlds Edison Division). He publishes as MrPrattASH on GitHub and @BroganMPratt on YouTube. Worth borrowing from him: non-blocking enum state machines that always time out, mechanism classes with an update() per loop, turret PD with soft limits. This code does three things differently. It uses custom feedforward + PI rather than the hub's built-in PIDF, which top DECODE teams dropped. It never localizes off the moving HIVE tags. And it avoids the unit mix-ups found in his Limelight and Pinpoint code.

The stack in October 2026: FTC SDK 12.0 (new AprilTag clusters; BIOBUZZ tags move), Pedro Pathing 3.0.2 (Foresight follower and AutoTune; your project is on 2.1.2, which this code targets), SolversLib 0.3.6, NextFTC 1.1.0, and Road Runner 1.0.1 (no release since January 2025). Upgrading to Pedro 3 is a separate step: the Maven names changed to com.pedropathing:revhub.

Mechanisms: DECODE's winning shape carries over: wide compliant intake, single-file transfer with a continuous feed wheel, and a 96 mm flywheel at 6000 rpm with added inertia. World Champion 30030 ran a 96 mm 60A wheel, 4 mm compression and 2 Hogback weights. 23511 fired only within 41 ticks/s of target. The new BIOBUZZ failure modes are backspin bounce-out and the two ball sizes. Both drove the shooter choice above.