{"index":[{"id":"battery-2x18650","title":"Battery belly (2 x 18650 holder)","kind":"bought","file":"battery-2x18650.json","does":"Bought: uxcell 2 x 18650 battery holder with leads, amazon.ca B092PMWQ4W (2-pack $9.39 CAD), plus two 18650 cells (cells not priced in the notes). Cuts its own pocket, adds its own mounts and opens its windows and holes. Provides power. Plugs into the brain: battery port.","seat":["-z",0],"size":[41,76,19],"mass_g":95},{"id":"boost-5v-2a","title":"5 V boost board (stand-in)","kind":"bought","file":"boost-5v-2a.json","does":"Bought: a 5 V 2 A boost from the 3.7 V pack (candidate in the notes: DAOKI 5 V 2 A boost/charge 5-pack, amazon.ca B08M37WBL8, $15.79); the size here is a stand-in until one is chosen and measured. Cuts its own pocket, adds its own mounts and opens its windows and holes. Provides power. Plugs into the brain: power port.","seat":["-y",1.6],"size":[22,4,17]},{"id":"bus-servo-adapter","title":"Bus servo driver (Waveshare Bus Servo Adapter A)","kind":"bought","file":"bus-servo-adapter.json","does":"Bought: Waveshare Bus Servo Adapter (A), serial bus servo driver board for ST/SC servos. Cuts its own pocket, adds its own mounts and opens its windows and holes. Provides servo-bus. Plugs into the brain: 2 serial port.","seat":["-y",4],"size":[42,1.6,33]},{"id":"cam-board","title":"Camera brain board","kind":"bought","file":"cam-board.json","does":"Bought: Waveshare ESP32-S3-CAM-OV5640 board. Cuts its own pocket, adds its own mounts and opens its windows and holes. Provides screen, camera, speaker, mic, pins, i2c and battery.","seat":["-y",6],"size":[37,10,37],"brain":true},{"id":"camera-ov5640","title":"Camera (OV5640 on its flex)","kind":"bought","file":"camera-ov5640.json","does":"Bought: comes with the Waveshare ESP32-S3-CAM-OV5640 board. Cuts its own pocket, adds its own mounts and opens its windows and holes. Brings camera lens ring. Plugs into the brain: camera port.","seat":["-y",3.6],"size":[10,8,10],"brings":["Camera lens ring"]},{"id":"charger-usbc-4410","title":"USB-C charger (Adafruit 4410)","kind":"bought","file":"charger-usbc-4410.json","does":"Bought: Adafruit Micro Lipo USB Type C LiPoly charger, product 4410. Cuts its own pocket, adds its own mounts and opens its windows and holes.","seat":["-y",3],"size":[24,6.4,19.05]},{"id":"fs90r-wheel-64","title":"Big wheel drive (FS90R, 64 mm)","kind":"bought","file":"fs90r-wheel-64.json","does":"Bought: FS90R continuous servo 2-pack with wheels (the servo and its horn; the 64 mm wheel and tyre are printed by 3D3D). Cuts its own pocket, adds its own mounts and opens its windows and holes. Brings wheel hub and tyre. Plugs into the brain: pwm port.","seat":["-y",1.6],"size":[23.2,22,12.5],"mirror":true,"drive":"wheel","brings":["Wheel hub","Tyre"],"mass_g":9},{"id":"fs90r-wheel","title":"Wheel drive (FS90R)","kind":"bought","file":"fs90r-wheel.json","does":"Bought: FS90R continuous servo 2-pack with wheels. Cuts its own pocket, adds its own mounts and opens its windows and holes. Brings wheel hub and tyre. Plugs into the brain: pwm port.","seat":["-z",10],"size":[23.2,22,12.5],"drive":"wheel","brings":["Wheel hub","Tyre"],"mass_g":9},{"id":"glide-tail","title":"Tail glide (third point)","kind":"printed","file":"glide-tail.json","does":"Printed by 3D3D. Opens its windows and holes. Brings glide.","seat":["-y",0],"brings":["Glide"]},{"id":"glide","title":"Glide","kind":"printed","file":"glide.json","does":"Printed by 3D3D. Opens its windows and holes. Brings glide.","seat":["-y",0],"brings":["Glide"]},{"id":"lcd-2in","title":"2\" touch screen","kind":"bought","file":"lcd-2in.json","does":"Bought: Waveshare 2\" capacitive touch LCD (18-pin). Cuts its own pocket, adds its own mounts and opens its windows and holes. Brings visor. Plugs into the brain: screen port.","seat":["-y",3.5],"size":[58.8,2.5,37.1],"brings":["Visor"],"mass_g":42},{"id":"m3-column-tall","title":"M3 screw column, tall (base to lid)","kind":"fixing","file":"m3-column-tall.json","does":"Joins two pieces: one carries it, the other gets the matching window or boss.","seat":["-y",0],"mirror":true,"joins":true},{"id":"m3-column","title":"M3 screw column (base to lid)","kind":"fixing","file":"m3-column.json","does":"Joins two pieces: one carries it, the other gets the matching window or boss.","seat":["-y",0],"mirror":true,"joins":true},{"id":"m3-insert","title":"M3 heat-set insert boss","kind":"fixing","file":"m3-insert.json","does":"Adds its boss, hole or column to the piece you pick.","seat":["-y",0],"mirror":true},{"id":"m3-screw","title":"M3 screw hole with head recess","kind":"fixing","file":"m3-screw.json","does":"Adds its boss, hole or column to the piece you pick.","seat":["-y",0],"mirror":true},{"id":"max98357a","title":"I2S amp (MAX98357A)","kind":"bought","file":"max98357a.json","does":"Bought: Adafruit MAX98357A I2S Class-D mono amp, product 3006. Cuts its own pocket, adds its own mounts and opens its windows and holes. Provides speaker. Plugs into the brain: i2s port.","seat":["-y",4],"size":[17.78,2.57,19.05]},{"id":"pca9685","title":"PWM driver board (PCA9685)","kind":"bought","file":"pca9685.json","does":"Bought: Adafruit PCA9685 16-channel 12-bit PWM/servo driver, product 815. Cuts its own pocket, adds its own mounts and opens its windows and holes. Provides pwm. Plugs into the brain: i2c port.","seat":["-y",6],"size":[62.23,12.1,25.4]},{"id":"scs0009-joint-posts","title":"Joint (SCS0009 bus servo) on posts","kind":"bought","file":"scs0009-joint-posts.json","does":"Bought: Feetech SCS0009 bus servo, 2-pack. Cuts its own pocket, adds its own mounts and opens its windows and holes. Plugs into the brain: servo-bus port.","seat":["-z",10],"size":[23.2,25.25,12.1],"mass_g":13.2},{"id":"scs0009-joint","title":"Joint (SCS0009 bus servo)","kind":"bought","file":"scs0009-joint.json","does":"Bought: Feetech SCS0009 bus servo, 2-pack. Cuts its own pocket, adds its own mounts and opens its windows and holes. Plugs into the brain: servo-bus port.","seat":["-z",10],"size":[23.2,25.25,12.1],"mass_g":13.2},{"id":"snap-hook","title":"Snap hook and its window","kind":"fixing","file":"snap-hook.json","does":"Joins two pieces: one carries it, the other gets the matching window or boss.","seat":["+x",2],"mirror":true,"joins":true},{"id":"speaker-1217","title":"Speaker 1217","kind":"bought","file":"speaker-1217.json","does":"Bought: comes with the Waveshare ESP32-S3-CAM-OV5640 board. Cuts its own pocket, adds its own mounts and opens its windows and holes. Plugs into the brain: speaker port.","seat":["-y",3],"size":[17,4,12]},{"id":"speaker-40mm","title":"Speaker 40 mm","kind":"bought","file":"speaker-40mm.json","does":"Bought: Adafruit 40 mm speaker, product 3968. Cuts its own pocket, adds its own mounts and opens its windows and holes. Plugs into the brain: speaker port.","seat":["-y",3],"size":[40,25,40]}],"recipes":{"battery-2x18650":{"id":"battery-2x18650","title":"Battery belly (2 x 18650 holder)","kind":"bought","buy":"uxcell 2 x 18650 battery holder with leads, amazon.ca B092PMWQ4W (2-pack $9.39 CAD), plus two 18650 cells (cells not priced in the notes)","frame":"origin = centre of the holder's bottom face (the face that lies on the floor); the holder is 41 wide (x), 76 long (y), 19 tall (z); -Y = the end its 13 cm leads come out of. The cradle stands on the floor round it.","size":[41,76,19],"sources":["research_notes/2026-11-02-R2-motion-power-parts.md lines 360-368: 2 x 18650 holder with leads, uxcell, 76 x 41 x 19 mm, 13 cm leads, holes not stated (MEASURE), amazon.ca B092PMWQ4W","same lines: 18650 cell Panasonic NCR18650B, max 18.25 x 65.10 mm, 47.5 g each (Panasonic sheet https://www.shoptronica.com/files/Panasonic-NCR18650.pdf); protected cells are about 19.3 x 70.0 and need the 70 mm","research_notes/2026-11-02-R8b-sourcing-part-two.md line 113: the battery option is a 2 x 18650 holder + a USB-C charger + a 5 V 2 A boost","research_notes/2026-11-02-R9-facts-closure.md 1b: the brain board has a GH1.25 2-pin 3.7 V battery port with a charger (ETA6098)"],"measure":["holder mounting holes (none stated: the cradle holds it by its outline, no screws)","holder mass (only the two cells are counted: 2 x 47.5 g = 95 g, so the real belly is heavier)","whether the holder joins the two cells in series (7.4 V, needs a buck: R4 voltage trap) or in parallel (3.7 V, what the brain port and a boost want): read the leads on the real holder before wiring","hold-down: the lip keeps the holder from lifting at the rear only; a velcro strap or a dab of hot glue at the front is untested","lead exit position (the end, the middle?) and the wire hole size (10 x 6 mm assumed)","current the cells give (not in the notes): the power rule uses the boost board"],"seat":["-z",0],"standin":{"add":[{"box":[-20.5,20.5,-38,38,0,19]}],"cut":[]},"keepout":[{"box":[-20.9,20.9,-38.4,38.4,0,19.4]}],"mounts":[{"box":[-23.4,23.4,38.4,40.4,-1,21.6]},{"box":[-23.4,23.4,35.4,38.4,19.6,21.6]},{"box":[-23.4,23.4,-40.4,-38.4,-1,12]},{"box":[20.9,23.1,-30,-18,-1,11],"copies":[[0,0,0],[0,48,0],[-44,0,0],[-44,48,0]]}],"cuts":[{"box":[-5,5,-40.6,-38.3,3,9]}],"pieces":[],"provides":[{"id":"pack","kind":"power","count":1,"note":"two 18650 cells (Panasonic NCR18650B: 47.5 g each); the current they can give is not in the notes (MEASURE), so the rules count the 5 V boost board, not the cells"}],"wiring":{"needs":[{"kind":"battery","count":1,"note":"the leads go to the brain's GH1.25 battery port through the USB-C charger board (cells to charger, charger to brain)"}],"cable":"13 cm leads from the holder; a second pair feeds the 5 V boost for the servos"},"mass_g":95,"current_ma":null},"boost-5v-2a":{"id":"boost-5v-2a","title":"5 V boost board (stand-in)","kind":"bought","buy":"a 5 V 2 A boost from the 3.7 V pack (candidate in the notes: DAOKI 5 V 2 A boost/charge 5-pack, amazon.ca B08M37WBL8, $15.79); the size here is a stand-in until one is chosen and measured","frame":"origin = centre of the board's back face, the face on the floor; the board fills y 0..4; -Y = toward the floor. STAND-IN: 22 x 17 x 4 mm is the MP1584EN buck module's size, borrowed only so the design has room reserved","size":[22,4,17],"sources":["research_notes/2026-11-02-R8-sourcing-amazon-aliexpress.md line 61 and R8b line 39/113: 5 V 2 A boost/charge boards, DAOKI B08M37WBL8 (a 2 A boost cannot feed four stalled servos; two FS90R stall at 1.4 A)","research_notes/2026-11-02-R2-motion-power-parts.md line 366: MP1584EN mini buck 22 x 17 x 4 mm, no holes (solder pads), used here ONLY as the stand-in size","research_notes/2026-11-02-R4-pip2-desk-companions.md line 165: 2S gives 8.4 V, above the servo limit; so the pack is wired 1S (parallel) and boosted"],"measure":["THE WHOLE SIZE: 22 x 17 x 4 is a stand-in, not a boost module (no boost module size is sourced yet); choose the board, measure it, replace the numbers","mounting: no holes known, so a printed frame holds it by its outline","mass (stand-in volume at 1 g/cm3 is used)","real output current and heat under two stalled servos (listing says 2 A)","where its input and output pads are, for the wire notch"],"seat":["-y",1.6],"standin":{"add":[{"box":[-11,11,0,4,-8.5,8.5]}],"cut":[]},"keepout":[{"box":[-11.2,11.2,-0.2,4.2,-8.7,8.7]}],"mounts":[{"box":[-13,-11.4,-1.6,4.4,-10.3,10.3]},{"box":[11.4,13,-1.6,4.4,-10.3,10.3]},{"box":[-11.4,11.4,-1.6,4.4,-10.3,-8.9]},{"box":[-11.4,11.4,-1.6,4.4,8.9,10.3]}],"cuts":[{"box":[-4,4,0.5,5,8.6,10.5]}],"pieces":[],"provides":[{"id":"servo-rail","kind":"power","count":1,"ma":2000,"note":"5 V 2 A from the listing (B08M37WBL8); not measured here"}],"wiring":{"needs":[{"kind":"power","count":1,"note":"its input pair from the cells (the pack's second lead)"}],"cable":"in from the pack, out to the two servo power wires"},"mass_g":null,"current_ma":null},"bus-servo-adapter":{"id":"bus-servo-adapter","title":"Bus servo driver (Waveshare Bus Servo Adapter A)","kind":"bought","buy":"Waveshare Bus Servo Adapter (A), serial bus servo driver board for ST/SC servos","frame":"origin = centre of the PCB's back face; -Y = toward the body wall it stands off; the PCB fills y 0..1.6, 42 wide (x), 33 tall (z); parts on the front (+Y), kept 2.5 mm in from the edges. Held in two edge rails with grooves: slide it in from above (+Z) before the lid goes on; a ledge under the rails stops it. Jack, screw terminal, servo headers and USB face +Y (plug room to y 32). The mounting holes are not used: their spacing is not published (MEASURE).","size":[42,1.6,33],"sources":["research_notes/2026-11-02-R2-motion-power-parts.md line 324: Waveshare Bus Servo Adapter (A), 42 x 33 mm, O2.5 holes (spacing not in the text), input 9-12.6 V matched to the servo, UART or USB by jumper, DC5521 jack + screw terminal, https://www.waveshare.com/wiki/Bus_Servo_Adapter_(A)","research_notes/2026-11-02-R4-pip2-desk-companions.md line 206: bus servo driver board, UART to half-duplex, 253 IDs, $16.35","research_notes/2026-11-02-R8-sourcing-amazon-aliexpress.md line 24: Waveshare $16.99 on amazon.ca"],"measure":["PCB thickness (1.6 assumed)","tallest part above the PCB (10.4 assumed, envelope to y 12)","mounting hole spacing (then posts can replace the rails)","mass","supply for SCS0009 servos: 6 V (the board passes its input to the servos)"],"seat":["-y",4],"standin":{"add":[{"box":[-21,21,0,1.6,-16.5,16.5]},{"box":[-18.5,18.5,1.6,12,-14,14]}],"cut":[]},"keepout":[{"box":[-21.2,21.2,-0.2,1.8,-16.7,16.7]},{"box":[-18.7,18.7,1.6,12.2,-14.2,14.2]},{"box":[-18.7,18.7,12.2,32,-14.2,14.2]}],"mounts":[{"box":[19,23.5,"-",3,-18.5,16.5]},{"box":[-23.5,-19,"-",3,-18.5,16.5]}],"cuts":[{"box":[18.9,21.4,-0.2,1.8,-16.7,17]},{"box":[-21.4,-18.9,-0.2,1.8,-16.7,17]}],"pieces":[],"provides":[{"id":"servo-bus","kind":"servo-bus","count":253,"note":"half-duplex serial bus, up to 253 servo IDs, daisy-chained 3-pin leads"}],"wiring":{"needs":[{"kind":"serial","count":2,"note":"TX and RX from the brain (UART mode by jumper), plus GND"}],"cable":"3 wires to the brain's serial pins; the servo bus leads plug into its headers; its own supply into the DC jack or terminal"},"mass_g":null,"current_ma":null},"cam-board":{"id":"cam-board","title":"Camera brain board","kind":"bought","brain":true,"buy":"Waveshare ESP32-S3-CAM-OV5640 board","frame":"origin = centre of the board's back face (the side with the USB-C, screwed to the body wall); -Y = toward that wall; the board fills y 0..10","size":[37,10,37],"sources":["research_notes/2026-11-02-R9-facts-closure.md 1b: 37 x 37, holes on a 32.6 square; pins table (UART header IO43/IO44 = TF card CMD/D0; I2C IO7/IO8 shared)","parts/bots/mini.py head: standoffs, pilots, USB-C opening"],"measure":["height (10 assumed)","USB-C position on the edge (opening assumed 4 mm above the bottom edge)","mass (not published)","hole diameter (M2 pilots assumed)"],"seat":["-y",6],"standin":{"add":[{"box":[-18.5,18.5,0,10,-18.5,18.5]}],"cut":[]},"keepout":[{"box":[-19,19,-0.2,10.5,-19,19]}],"mounts":[{"cyl":"y","r":2.75,"span":["-",0],"at":[0,0],"copies":[[-16.3,0,-16.3],[16.3,0,-16.3],[-16.3,0,16.3],[16.3,0,16.3]]}],"cuts":[{"cyl":"y","r":0.8,"span":[0.1,-3],"at":[0,0],"copies":[[-16.3,0,-16.3],[16.3,0,-16.3],[-16.3,0,16.3],[16.3,0,16.3]]},{"rrect":"y","w":14,"h":8,"r":2,"span":[-6.2,-3.9],"at":[0,-14.5]}],"pieces":[],"provides":[{"id":"screen-port","kind":"screen","count":1,"note":"18-pin FPC; Waveshare 3.5, 2.8, 2 and 1.83 inch touch modules"},{"id":"camera-port","kind":"camera","count":1,"note":"24-pin DVP"},{"id":"speaker","kind":"speaker","count":1,"note":"NS4150B amp on the board"},{"id":"mics","kind":"mic","count":2,"note":"ES7210"},{"id":"uart-header","kind":"pins","pins":["IO43","IO44"],"as":["pwm","serial"],"note":"the TF card's CMD and D0: no TF card when these are used"},{"id":"i2c","kind":"i2c","pins":["IO7","IO8"],"note":"shared with the codec and touch chips"},{"id":"battery","kind":"battery","count":1,"note":"GH1.25 2-pin 3.7 V with charger (ETA6098)"}],"power":"USB-C 5 V","wiring":{"needs":[]},"mass_g":null,"current_ma":null},"camera-ov5640":{"id":"camera-ov5640","title":"Camera (OV5640 on its flex)","kind":"bought","buy":"comes with the Waveshare ESP32-S3-CAM-OV5640 board","frame":"origin = centre of the module's front face; -Y looks out; module y 0..8","size":[10,8,10],"sources":["parts/bots/mini.py head: module, channel ribs, stop pillar, lens ring"],"measure":["module size (10 x 10 x 8 assumed)","lens diameter (7.5 assumed)","flex length from the board"],"seat":["-y",3.6],"standin":{"add":[{"box":[-5,5,0,8,-5,5]}],"cut":[]},"keepout":[{"box":[-5.3,5.3,-0.2,8.3,-5.3,5.3]},{"cyl":"y","r":6.7,"span":[-1.7,-0.2],"at":[0,0]}],"mounts":[{"box":[5.3,6.5,2,"+",-6.2,"+"]},{"box":[-6.5,-5.3,2,"+",-6.2,"+"]},{"box":[-6.5,6.5,2,"+",-6.2,-5]},{"cyl":"y","r":2,"span":[8.3,"+"],"at":[3,0]}],"cuts":[{"cyl":"y","r":5.65,"span":[-3.7,-1.5],"at":[0,0]}],"pieces":[{"id":"lens-ring","title":"Camera lens ring","material":"PETG clear","colour":"glow","print":"y_back_down","add":[{"cyl":"y","r":5.5,"span":[-3.6,-1.6],"at":[0,0]},{"cyl":"y","r":6.5,"span":[-1.6,-0.4],"at":[0,0]}],"cut":[{"cyl":"y","r":3.75,"span":[-3.7,-0.3],"at":[0,0]}]}],"wiring":{"needs":[{"kind":"camera","count":1}],"cable":"its own flex into the brain's camera port"},"mass_g":null,"current_ma":null},"charger-usbc-4410":{"id":"charger-usbc-4410","title":"USB-C charger (Adafruit 4410)","kind":"bought","buy":"Adafruit Micro Lipo USB Type C LiPoly charger, product 4410","frame":"origin = centre of the board's back face, the face that sits on the posts; -Y = toward the posts (the floor or a wall); the board fills y 0..6.4; its USB-C end is +X, and a window is cut through the shell beyond it","size":[24,6.4,19.05],"sources":["research_notes/2026-11-02-R2-motion-power-parts.md lines 360-368: Adafruit #4410 USB-C LiPo charger 24.0 x 19.05 x 6.4 mm (USB-C overhangs 1.1 mm), 4 x O2.5 holes at 17.8 x 14.0 mm centres, STEP-measured from https://github.com/adafruit/Adafruit_CAD_Parts/tree/main/4410%20Micro%20Lipo%20USBC (MIT)","shared/recipes/pca9685.json: the same board-on-posts pattern (posts from the surface, pilot holes for the O2.5 holes)"],"measure":["centring of the four holes on the 24.0 mm length (assumed centred; the connector overhang may shift them)","mass (not in the STEP or the notes)","USB-C window 11 x 5.4 mm and its height above the board (a standard receptacle is about 9 x 3.3 mm: the window is a guess with room, not a measurement)","which pads/connector take the cells and the load (a JST on the real board: lead lengths decide where it sits)"],"seat":["-y",3],"standin":{"add":[{"box":[-12,12,0,6.4,-9.525,9.525]}],"cut":[]},"keepout":[{"box":[-12.4,12.4,-0.2,6.8,-9.925,9.925]}],"mounts":[{"box":[-2.75,2.75,"-",0,-2.75,2.75],"copies":[[-8.9,0,-7],[8.9,0,-7],[-8.9,0,7],[8.9,0,7]]}],"cuts":[{"cyl":"y","r":1.05,"span":[0.1,-3],"at":[0,0],"copies":[[-8.9,0,-7],[8.9,0,-7],[-8.9,0,7],[8.9,0,7]]},{"box":[11.9,15.5,0.6,6,-5.5,5.5]}],"pieces":[],"wiring":{"needs":[],"cable":"USB-C in; JST to the cells; its output pair to the brain battery port (no port counted: the cells own it)"},"mass_g":null,"current_ma":null},"fs90r-wheel-64":{"id":"fs90r-wheel-64","title":"Big wheel drive (FS90R, 64 mm)","kind":"bought","mirror":true,"buy":"FS90R continuous servo 2-pack with wheels (the servo and its horn; the 64 mm wheel and tyre are printed by 3D3D)","frame":"origin = on the shaft axis at the servo's top (shaft) face; -Y = the shaft and wheel, pointing out of the bot; +Z up; the servo lies on its side. The wheel is 64 mm across (tyre r 32, 10 mm wide) on the outside of the body: its axle is 32 mm above the floor it rolls on.","size":[23.2,22,12.5],"sources":["research_notes/2026-11-02-R9-facts-closure.md (FS90R body 23.2 x 12.5 x 22, flange holes 27.0-29.7 apart: drawings disagree)","FS90 sheet https://www.pololu.com/file/0J1435/FS90-specs.pdf: 9 g, stall 700 mA at 4.8 V","research_notes/2026-11-02-R8-sourcing-amazon-aliexpress.md line 81: Feetech FS90R listing, 1.5 kg torque, 4.8-6 V, PWM","shared/recipes/fs90r-wheel.json: the servo stand-in, keep-outs, flange plate, slot and horn interface are copied from it unchanged","docs/work-orders/BAB-0062-mini-v2-big-wheels.md scope 1: tyre outer radius 32, about 10 mm wide, rim and spokes (not a solid disc), a recess for the horn, drive.radius 32, ground_z -32","docs/work-orders/BAB-0062 context: 1.5 kg.cm stall at a 32 mm radius is about 0.47 kgf a wheel; at the assumed 110 rpm about 0.37 m/s"],"measure":["flange height and thickness","flange hole spacing (28.4 used, the middle of the drawings)","horn (disc 21 x 1.5 assumed)","FS90R mass and current (FS90 figures used)","rpm at 5 V (110 assumed; it sets the top speed, 0.37 m/s with this wheel)","the TPU tyre on the PETG rim: the tyre inner radius equals the rim, 27.0 mm, line to line (the check forbids overlaps); TPU wants a snug stretch, so print one and try 26.6 mm; tread depth 1.6 mm and 32 lugs are looks, not measurements","the bearing of the 64 mm wheel on the FS90R horn: the horn is a small plastic part; check the screw does not strip under the bot sitting on the wheel (about 0.1 kg a wheel)"],"seat":["-y",1.6],"standin":{"add":[{"box":[-5.9,17.3,0,22,-6.25,6.25]},{"box":[-10.55,21.95,3.5,6,-6.25,6.25]},{"cyl":"y","r":2.5,"span":[-3.5,0],"at":[0,0]},{"cyl":"y","r":10.5,"span":[-5,-3.5],"at":[0,0]}],"cut":[]},"keepout":[{"box":[-6.1,17.5,-0.2,22.2,-6.45,6.45]},{"box":[-10.75,22.15,3.3,6.2,-6.45,6.45]},{"cyl":"y","r":33,"span":[-19.6,-3],"at":[0,0]},{"cyl":"y","r":2.7,"span":[-3.1,0],"at":[0,0]}],"mounts":[{"box":[-13,24.5,6.1,9.6,"-",8]}],"cuts":[{"box":[-6.1,17.5,6,9.7,-6.45,9]},{"cyl":"y","r":0.8,"span":[6,9.7],"at":[-8.5,0],"copies":[[0,0,0],[28.4,0,0]]}],"pieces":[{"id":"hub","title":"Wheel hub","material":"PETG","colour":"orange","print":"y_front_down","add":[{"rev":"y","pts":[[0,-18.8],[29.2,-18.8],[29.2,-17.4],[27,-17.4],[27,-7.4],[29.2,-5],[25,-5],[25,-15],[13,-15],[13,-5],[0,-5]],"at":[0,0]}],"cut":[{"prism":"y","pts":[[-3.5,22.934],[-6.203,22.355],[-8.818,21.459],[-11.307,20.258],[-13.637,18.769],[-15.772,17.014],[-17.684,15.017],[-19.344,12.808],[-20.73,10.416],[-13.279,7.995],[-12.097,9.691],[-10.699,11.215],[-9.111,12.54],[-7.36,13.641],[-5.479,14.499],[-3.5,15.1]],"span":[-18.900000000000002,-14.9]},{"prism":"y","pts":[[-22.894,3.758],[-23.178,1.009],[-23.134,-1.755],[-22.761,-4.494],[-22.065,-7.169],[-21.055,-9.743],[-19.747,-12.178],[-18.158,-14.44],[-16.312,-16.497],[-11.707,-10.159],[-12.955,-8.51],[-13.973,-6.71],[-14.741,-4.79],[-15.248,-2.785],[-15.483,-0.73],[-15.442,1.337]],"span":[-18.900000000000002,-14.9]},{"prism":"y","pts":[[-10.649,-20.612],[-8.122,-21.732],[-5.48,-22.544],[-2.759,-23.035],[0,-23.2],[2.759,-23.035],[5.48,-22.544],[8.122,-21.732],[10.649,-20.612],[6.044,-14.273],[4.09,-14.951],[2.063,-15.362],[0,-15.5],[-2.063,-15.362],[-4.09,-14.951],[-6.044,-14.273]],"span":[-18.900000000000002,-14.9]},{"prism":"y","pts":[[16.312,-16.497],[18.158,-14.44],[19.747,-12.178],[21.055,-9.743],[22.065,-7.169],[22.761,-4.494],[23.134,-1.755],[23.178,1.009],[22.894,3.758],[15.442,1.337],[15.483,-0.73],[15.248,-2.785],[14.741,-4.79],[13.973,-6.71],[12.955,-8.51],[11.707,-10.159]],"span":[-18.900000000000002,-14.9]},{"prism":"y","pts":[[20.73,10.416],[19.344,12.808],[17.684,15.017],[15.772,17.014],[13.637,18.769],[11.307,20.258],[8.818,21.459],[6.203,22.355],[3.5,22.934],[3.5,15.1],[5.479,14.499],[7.36,13.641],[9.111,12.54],[10.699,11.215],[12.097,9.691],[13.279,7.995]],"span":[-18.900000000000002,-14.9]},{"cyl":"y","r":10.7,"span":[-4.9,-6.5],"at":[0,0]},{"cyl":"y","r":3,"span":[-18.900000000000002,-4.9],"at":[0,0]},{"cyl":"y","r":1.1,"span":[-18.900000000000002,-4.9],"at":[0,7],"copies":[[0,0,0],[0,0,-14]]}]},{"id":"tyre","title":"Tyre","material":"TPU 95A","colour":"tpu","print":"y_front_down","add":[{"prism":"y","pts":[[-2.742,-30.276],[-1.633,-31.958],[1.633,-31.958],[2.742,-30.276],[3.217,-30.229],[4.633,-31.663],[7.836,-31.026],[8.596,-29.159],[9.053,-29.021],[10.721,-30.151],[13.739,-28.901],[14.119,-26.922],[14.541,-26.697],[16.397,-27.48],[19.113,-25.665],[19.1,-23.65],[19.47,-23.347],[21.443,-23.753],[23.753,-21.443],[23.347,-19.47],[23.65,-19.1],[25.665,-19.113],[27.48,-16.397],[26.697,-14.541],[26.922,-14.119],[28.901,-13.739],[30.151,-10.721],[29.021,-9.053],[29.159,-8.596],[31.026,-7.836],[31.663,-4.633],[30.229,-3.217],[30.276,-2.742],[31.958,-1.633],[31.958,1.633],[30.276,2.742],[30.229,3.217],[31.663,4.633],[31.026,7.836],[29.159,8.596],[29.021,9.053],[30.151,10.721],[28.901,13.739],[26.922,14.119],[26.697,14.541],[27.48,16.397],[25.665,19.113],[23.65,19.1],[23.347,19.47],[23.753,21.443],[21.443,23.753],[19.47,23.347],[19.1,23.65],[19.113,25.665],[16.397,27.48],[14.541,26.697],[14.119,26.922],[13.739,28.901],[10.721,30.151],[9.053,29.021],[8.596,29.159],[7.836,31.026],[4.633,31.663],[3.217,30.229],[2.742,30.276],[1.633,31.958],[-1.633,31.958],[-2.742,30.276],[-3.217,30.229],[-4.633,31.663],[-7.836,31.026],[-8.596,29.159],[-9.053,29.021],[-10.721,30.151],[-13.739,28.901],[-14.119,26.922],[-14.541,26.697],[-16.397,27.48],[-19.113,25.665],[-19.1,23.65],[-19.47,23.347],[-21.443,23.753],[-23.753,21.443],[-23.347,19.47],[-23.65,19.1],[-25.665,19.113],[-27.48,16.397],[-26.697,14.541],[-26.922,14.119],[-28.901,13.739],[-30.151,10.721],[-29.021,9.053],[-29.159,8.596],[-31.026,7.836],[-31.663,4.633],[-30.229,3.217],[-30.276,2.742],[-31.958,1.633],[-31.958,-1.633],[-30.276,-2.742],[-30.229,-3.217],[-31.663,-4.633],[-31.026,-7.836],[-29.159,-8.596],[-29.021,-9.053],[-30.151,-10.721],[-28.901,-13.739],[-26.922,-14.119],[-26.697,-14.541],[-27.48,-16.397],[-25.665,-19.113],[-23.65,-19.1],[-23.347,-19.47],[-23.753,-21.443],[-21.443,-23.753],[-19.47,-23.347],[-19.1,-23.65],[-19.113,-25.665],[-16.397,-27.48],[-14.541,-26.697],[-14.119,-26.922],[-13.739,-28.901],[-10.721,-30.151],[-9.053,-29.021],[-8.596,-29.159],[-7.836,-31.026],[-4.633,-31.663],[-3.217,-30.229]],"span":[-17.4,-7.4]}],"cut":[{"cyl":"y","r":27,"span":[-17.5,-7.300000000000001],"at":[0,0]}]}],"drive":{"kind":"wheel","radius":32,"axis":"-y","ground_z":-32,"stall_kgcm":1.5,"rpm":110,"tyre_contact":"crown","rpm_note":"110 rpm is an assumption until measured (rpm at 5 V is on the measure list); torque from the listing. With a 32 mm radius that is 0.37 m/s and about 0.47 kgf a wheel."},"wiring":{"needs":[{"kind":"pwm","count":1}],"cable":"3-wire servo lead, 5 V"},"mass_g":9,"current_ma":{"stall":700,"volts":4.8}},"fs90r-wheel":{"id":"fs90r-wheel","title":"Wheel drive (FS90R)","kind":"bought","buy":"FS90R continuous servo 2-pack with wheels","frame":"origin = on the shaft axis at the servo's top (shaft) face; -Y = the shaft and wheel, pointing out of the bot; +Z up; the servo lies on its side","size":[23.2,22,12.5],"sources":["research_notes/2026-11-02-R9-facts-closure.md (FS90R body 23.2 x 12.5 x 22, flange holes 27.0-29.7 apart: drawings disagree)","FS90 sheet https://www.pololu.com/file/0J1435/FS90-specs.pdf: 9 g, stall 700 mA at 4.8 V","parts/bots/mini.py base: U plate, rest, wheel slot, hub, tyre","research_notes/2026-11-02-R8-sourcing-amazon-aliexpress.md line 81: Feetech FS90R listing, 1.5 kg torque, 4.8-6 V, PWM"],"measure":["flange height and thickness","flange hole spacing (28.4 used, the middle of the drawings)","horn (disc 21 x 1.5 assumed)","FS90R mass and current (FS90 figures used)","rpm at 5 V"],"seat":["-z",10],"standin":{"add":[{"box":[-5.9,17.3,0,22,-6.25,6.25]},{"box":[-10.55,21.95,3.5,6,-6.25,6.25]},{"cyl":"y","r":2.5,"span":[-3.5,0],"at":[0,0]},{"cyl":"y","r":10.5,"span":[-5,-3.5],"at":[0,0]}],"cut":[]},"keepout":[{"box":[-6.1,17.5,-0.2,22.2,-6.45,6.45]},{"box":[-10.75,22.15,3.3,6.2,-6.45,6.45]},{"box":[-16.5,16.5,-13.5,-3,"-",16.5]},{"cyl":"y","r":2.7,"span":[-3.1,0],"at":[0,0]}],"mounts":[{"box":[-13,24.5,6.1,9.6,"-",8]},{"box":[-5,16,16,20,"-",-6.3]}],"cuts":[{"box":[-6.1,17.5,6,9.7,-6.45,9]},{"cyl":"y","r":0.8,"span":[6,9.7],"at":[-8.5,0],"copies":[[0,0,0],[28.4,0,0]]}],"pieces":[{"id":"hub","title":"Wheel hub","material":"PETG","colour":"graphite","print":"y_front_down","add":[{"rev":"y","pts":[[0,-12],[13,-12],[12,-11],[12,-6],[13,-5],[0,-5]],"at":[0,0]}],"cut":[{"cyl":"y","r":10.7,"span":[-4.9,-6.5],"at":[0,0]},{"cyl":"y","r":3,"span":[-12.1,-4.9],"at":[0,0]},{"cyl":"y","r":1.1,"span":[-12.1,-4.9],"at":[0,7],"copies":[[0,0,0],[0,0,-14]]}]},{"id":"tyre","title":"Tyre","material":"TPU 95A","colour":"tpu","print":"y_front_down","add":[{"cyl":"y","r":15,"span":[-11,-6],"at":[0,0]}],"cut":[{"cyl":"y","r":12,"span":[-11.1,-5.9],"at":[0,0]}]}],"drive":{"kind":"wheel","radius":15,"axis":"-y","ground_z":-15,"stall_kgcm":1.5,"rpm":110,"rpm_note":"110 rpm is an assumption until measured (rpm at 5 V is on the measure list); torque from the listing"},"wiring":{"needs":[{"kind":"pwm","count":1}],"cable":"3-wire servo lead, 5 V"},"mass_g":9,"current_ma":{"stall":700,"volts":4.8}},"glide-tail":{"id":"glide-tail","title":"Tail glide (third point)","kind":"printed","contact":"ground","buy":"PTFE glass-cloth tape 10 mm x 10 m (a pad on the dome); M3 x 4 self-tapping screw","frame":"origin = centre of the glide's flat face, against the body's underside; -Y = the dome, toward the floor. The dome is 3.1 mm tall: the belly rides 3.1 mm over the floor and the dome is the bot's third point of contact (BAB-0062: two big tyres in front, this behind; it touches the floor, it does not rock).","sources":["parts/bots/mini.py base: domed glide, M3 x 5 self-tap from inside","docs/work-orders/BAB-0062-mini-v2-big-wheels.md scope 3: one rear glide so it stands on three points"],"measure":["the sandbox gives the PTFE-taped dome a friction of 0.08 against the floor: PTFE on a hard floor is slippery, but 0.08 is a model number, not a measurement (the old glide used 0.15 in shared/gen/sim.mjs); measure it with a pull gauge on the finished glide"],"seat":["-y",0],"standin":{"add":[],"cut":[]},"keepout":[],"mounts":[],"cuts":[{"cyl":"y","r":1.7,"span":[-0.1,2.1],"at":[0,0]}],"pieces":[{"id":"glide","title":"Glide","material":"PETG + PTFE tape","colour":"graphite","print":"y_back_down","add":[{"rev":"y","pts":[[0,0],[0,-3.1],[2.2,-3.1],[3.183,-3.012],[4.1,-2.757],[4.887,-2.35],[5.491,-1.82],[5.87,-1.202],[6,-0.539],[6,0]],"at":[0,0]}],"cut":[{"cyl":"y","r":1.3,"span":[-1.8,0.1],"at":[0,0]}]}],"wiring":{"needs":[]},"mass_g":null,"current_ma":null,"friction":0.08},"glide":{"id":"glide","title":"Glide","kind":"printed","contact":"rock","buy":"PTFE glass-cloth tape 10 mm x 10 m (a pad on the dome); M3 x 4 self-tapping screw","frame":"origin = centre of the glide's flat face, against the body's underside; -Y = the dome, toward the floor. The dome is 3.1 mm tall (was 4.6): with the Mini's glides 1.5 mm above the tyres' bottom the tyres carry the bot and keep their grip where the floor bends up (a ramp, a step); the bot rocks onto a glide only when it tips (2026-11-03, the test room's ramp finding).","sources":["parts/bots/mini.py base: domed glide, M3 x 5 self-tap from inside"],"measure":[],"seat":["-y",0],"standin":{"add":[],"cut":[]},"keepout":[],"mounts":[],"cuts":[{"cyl":"y","r":1.7,"span":[-0.1,2.1],"at":[0,0]}],"pieces":[{"id":"glide","title":"Glide","material":"PETG + PTFE tape","colour":"graphite","print":"y_back_down","add":[{"rev":"y","pts":[[0,0],[0,-3.1],[2.2,-3.1],[3.183,-3.012],[4.1,-2.757],[4.887,-2.35],[5.491,-1.82],[5.87,-1.202],[6,-0.539],[6,0]],"at":[0,0]}],"cut":[{"cyl":"y","r":1.3,"span":[-1.8,0.1],"at":[0,0]}]}],"wiring":{"needs":[]},"mass_g":null,"current_ma":null},"lcd-2in":{"id":"lcd-2in","title":"2\" touch screen","kind":"bought","buy":"Waveshare 2\" capacitive touch LCD (18-pin)","frame":"origin = centre of the glass front face; -Y looks out of the bot; +Z up; glass y 0..2.5, board y 2.5..6","size":[58.8,2.5,37.1],"sources":["research_notes/2026-11-02-R9-facts-closure.md 1d: module 58.8 x 37.1, display area 40.8 x 30.6, rear PCB 48.2 x 35, holes 42.2 x 29.0 O2.0-2.2, 42 g; https://www.waveshare.com/2inch-capacitive-touch-lcd.htm","parts/bots/mini.py head: posts, pins, visor, window"],"measure":["module thickness (6.0 assumed: glass 2.5 + board 3.5)","display area centred on the glass (assumed)","FPC exit side and length"],"seat":["-y",3.5],"standin":{"add":[{"box":[-29.4,29.4,0,2.5,-18.55,18.55]},{"box":[-24.1,24.1,2.5,6,-17.5,17.5]}],"cut":[{"cyl":"y","r":1.05,"span":[-0.1,6.1],"at":[0,0],"copies":[[-21.1,0,-14.5],[21.1,0,-14.5],[-21.1,0,14.5],[21.1,0,14.5]]}]},"display":{"w":40.8,"h":30.6,"at":[0,0,0],"px":[320,240],"driver":"ST7789","touch":"CST816D"},"keepout":[{"box":[-29.6,29.6,-0.1,2.7,-18.75,18.75]},{"box":[-24.3,24.3,2.5,6.2,-17.7,17.7]},{"box":[-26.2,26.2,-1.6,0,-18,18]}],"mounts":[{"cyl":"y","r":2.25,"span":[6.2,"+"],"at":[0,0],"copies":[[-21.1,0,-14.5],[21.1,0,-14.5],[-21.1,0,14.5],[21.1,0,14.5]]},{"cyl":"y","r":0.9,"span":[4.6,6.3],"at":[0,0],"copies":[[-21.1,0,-14.5],[21.1,0,-14.5],[-21.1,0,14.5],[21.1,0,14.5]]},{"box":[26.2,27.4,-1.5,-0.1,-6,6]},{"box":[-27.4,-26.2,-1.5,-0.1,-6,6]}],"cuts":[{"rrect":"y","w":41.8,"h":31.6,"r":1.5,"span":[-3.7,-1.4],"at":[0,0]}],"pieces":[{"id":"visor","title":"Visor","material":"PETG clear smoked","colour":"smoke","print":"y_front_down","add":[{"rrect":"y","w":52,"h":35.6,"r":3,"span":[-1.5,0],"at":[0,0]}]}],"wiring":{"needs":[{"kind":"screen","count":1}],"cable":"18-pin FPC to the brain's screen port"},"mass_g":42,"current_ma":null},"m3-column-tall":{"id":"m3-column-tall","title":"M3 screw column, tall (base to lid)","kind":"fixing","mirror":true,"buy":"M3 x 40 screw (self-taps into the lid's boss)","frame":"origin = on the body's underside (the bed face) on the column's axis; +Y = up the column. The column and its screw recess go on `piece` (the lower piece); the boss and pilot hole on `other` (the lid), stopping 0.2 short of the column. For lids 37..41 mm above the underside (m3-column is the short one).","sources":["m3-column (parts/bots/mini.py base_chassis / base_lid: column r 4.75, clearance r 1.7, head recess r 3.25 x 3, lid boss r 3.25, pilot r 1.3), made 10 mm taller for the desk companion's 44 mm base"],"measure":["screw length for the real lid height (M3 x 40 assumed: 37 mm in the column and lid boss, 3 mm head recess)"],"seat":["-y",0],"standin":{"add":[],"cut":[]},"keepout":[],"mounts":[{"cyl":"y","r":4.75,"span":[0,30],"at":[0,0]}],"cuts":[{"cyl":"y","r":1.7,"span":[-0.1,30.1],"at":[0,0]},{"cyl":"y","r":3.25,"span":[-0.1,3],"at":[0,0]}],"other":{"mounts":[{"cyl":"y","r":3.25,"span":[30.2,"+"],"at":[0,0]}],"cuts":[{"cyl":"y","r":1.3,"span":[30.1,40],"at":[0,0]}]},"pieces":[],"wiring":{"needs":[]}},"m3-column":{"id":"m3-column","title":"M3 screw column (base to lid)","kind":"fixing","mirror":true,"buy":"M3 x 30 screw (self-taps into the lid's boss)","frame":"origin = on the body's underside (the bed face) on the column's axis; +Y = up the column. The column and its screw recess go on `piece` (the lower piece); the boss and pilot hole on `other` (the lid), stopping 0.2 short of the column. For lids 27..31 mm above the underside.","sources":["parts/bots/mini.py base_chassis / base_lid: column r 4.75 x 20, clearance r 1.7, head recess r 3.25 x 3; lid boss r 3.25 from 20.2, pilot r 1.3 to 29"],"measure":["screw length for the real lid height"],"seat":["-y",0],"standin":{"add":[],"cut":[]},"keepout":[],"mounts":[{"cyl":"y","r":4.75,"span":[0,20],"at":[0,0]}],"cuts":[{"cyl":"y","r":1.7,"span":[-0.1,20.1],"at":[0,0]},{"cyl":"y","r":3.25,"span":[-0.1,3],"at":[0,0]}],"other":{"mounts":[{"cyl":"y","r":3.25,"span":[20.2,"+"],"at":[0,0]}],"cuts":[{"cyl":"y","r":1.3,"span":[20.1,29],"at":[0,0]}]},"pieces":[],"wiring":{"needs":[]}},"m3-insert":{"id":"m3-insert","title":"M3 heat-set insert boss","kind":"fixing","mirror":true,"buy":"M3 brass heat-set insert (about 4 mm across, 5 mm long)","frame":"origin = the insert's mouth on the body's skin; -Y = out of the body; the insert goes in along +Y; +X = toward the nearest side wall (the boss is tied to it); +Z must be the piece's print-up direction (the hole is a teardrop pointing +Z). Mirror it in X for the other side.","sources":["parts/bots/mini.py head_tub: insert block 2 mm round the insert, fused to the side wall, teardrop r 2 x 6 deep"],"measure":["insert outer size and the hole the maker asks for (r 2.0 used)"],"seat":["-y",0],"standin":{"add":[],"cut":[]},"keepout":[],"mounts":[{"box":[-4,"+",0,10,-5,5]}],"cuts":[{"tear":"y","r":2,"span":[-0.1,6],"at":[0,0],"tip":"+z"}],"pieces":[],"wiring":{"needs":[]}},"m3-screw":{"id":"m3-screw","title":"M3 screw hole with head recess","kind":"fixing","mirror":true,"buy":"M3 x 8 pan-head screw","frame":"origin = on the face the screw head sits on; -Y = the head's side; the shank goes along +Y (6 mm of clearance hole); the head sits in a 1.5 mm recess","sources":["parts/bots/mini.py base_lid: clearance r 1.7, head recess r 3.25 x 1.5"],"measure":[],"seat":["-y",0],"standin":{"add":[],"cut":[]},"keepout":[],"mounts":[],"cuts":[{"cyl":"y","r":1.7,"span":[-0.1,6],"at":[0,0]},{"cyl":"y","r":3.25,"span":[-0.1,1.5],"at":[0,0]}],"pieces":[],"wiring":{"needs":[]}},"max98357a":{"id":"max98357a","title":"I2S amp (MAX98357A)","kind":"bought","buy":"Adafruit MAX98357A I2S Class-D mono amp, product 3006","frame":"origin = centre of the board's back (solder) face, the side screwed to the body wall; -Y = toward that wall; the board fills y 0..2.57; 17.78 wide (x), 19.05 tall (z); the 7-pin I2S header (pins at z -6.985, x -7.62..7.62) and the 2-pin speaker terminal (z +5.97) both face +Y, so the plug room runs to y 22.6; two O2.5 mounting holes run through the board at x +/-6.35, z +6.985","size":[17.78,2.57,19.05],"sources":["parts/vendor/measured/3006_max98357a.json (measured from parts/vendor/adafruit-cad-parts/3006_max98357a.step, Adafruit MIT): size [17.78, 19.05, 2.57], bbox_min [0, 0, 0]; mounting holes r 1.25 along the STEP z axis at (2.54, 16.51) and (15.24, 16.51) -> x +/-6.35, z +6.985 about the bbox centre; 7 header pins r 0.5 at STEP y 2.54 (z -6.985, x -7.62..7.62 at 2.54 pitch), 2 terminal pins r 0.5 at STEP y 15.494 (z +5.97, x -1.80/+1.70)","research_notes/2026-11-02-R3-brains-sensors-screens-audio.md:204-205: 17.78 x 19.05 x 2.57 mm, 2 x O2.5 mm at (2.54, 16.51) and (15.24, 16.51), 3.2 W into 4 ohm and 1.8 W into 8 ohm at 5 V; https://github.com/adafruit/Adafruit_CAD_Parts (MIT)","shared/recipes/pca9685.json: board-on-standoffs pattern and the plug-room keep-out over the +Y connectors (R01 review fix)"],"measure":["mass (not in the measured STEP or the product page)","header pin and terminal block height above the board top (inside the 2.57 mm envelope)"],"seat":["-y",4],"standin":{"add":[{"box":[-8.89,8.89,0,2.57,-9.525,9.525]}],"cut":[]},"keepout":[{"box":[-9.1,9.1,-0.2,2.77,-9.75,9.75]},{"box":[-9.1,9.1,2.77,22.6,-9.75,9.75]}],"mounts":[{"cyl":"y","r":2.75,"span":["-",0],"at":[0,0],"copies":[[-6.35,0,6.985],[6.35,0,6.985]]}],"cuts":[{"cyl":"y","r":1.05,"span":[0.1,-3],"at":[0,0],"copies":[[-6.35,0,6.985],[6.35,0,6.985]]}],"pieces":[],"provides":[{"id":"speaker","kind":"speaker","count":1,"note":"mono Class-D output on the 2-pin terminal; 3.2 W into 4 ohm, 1.8 W into 8 ohm at 5 V"}],"power":"Vin 3-5.5 V on the 7-pin header (with GND); 3.2 W into 4 ohm at 5 V","wiring":{"needs":[{"kind":"i2s","count":1,"note":"BCLK, LRC, DIN plus Vin/GND on the 7-pin header; GAIN and SD pins set gain and shutdown"}],"cable":"7-pin header lead to the brain's I2S port; 2-wire speaker cable into the amp's terminal block"},"mass_g":null,"current_ma":null},"pca9685":{"id":"pca9685","title":"PWM driver board (PCA9685)","kind":"bought","buy":"Adafruit PCA9685 16-channel 12-bit PWM/servo driver, product 815","frame":"origin = centre of the board's back (solder) face, the side screwed to the body wall; -Y = toward that wall; the board fills y 0..12.1; 62.23 wide (x), 25.4 tall (z); servo headers, power terminal and I2C header face +Y (plug room to y 32); the four mounting holes run through the board at x +/-27.94, z +/-9.525","size":[62.23,12.1,25.4],"sources":["parts/vendor/measured/815_pca9685.json (measured from parts/vendor/adafruit-cad-parts/815_pca9685.step, Adafruit MIT): size [62.23, 25.4, 12.1], bbox_min [-1.905, -6.477, -2.01]; mounting holes r 1.25 along the STEP z axis at (1.27, -3.302), (57.15, -3.302), (1.27, 15.748), (57.15, 15.748) -> 55.88 x 19.05 about the bbox centre -> x +/-27.94, z +/-9.525 in this frame","research_notes/2026-11-02-R2-motion-power-parts.md:323: PCB 62.2 x 25.4 mm, 12.1 mm tall with headers, 4 x O2.5 holes at 55.8 x 19.0 mm centres, I2C, 12-bit PWM, https://github.com/adafruit/Adafruit_CAD_Parts/tree/main/815%20Servo%20Driver%2016%20Channel (MIT)","shared/recipes/cam-board.json: board-on-standoffs pattern (posts from the wall + pilot cuts, seat -y)"],"measure":["mass (not in the measured STEP or the product page)","per-channel current draw (servo stall current is the servo's, not the board's)","header pin height above the board top (inside the 12.1 mm envelope)"],"seat":["-y",6],"standin":{"add":[{"box":[-31.115,31.115,0,12.1,-12.7,12.7]}],"cut":[]},"keepout":[{"box":[-31.4,31.4,-0.2,12.4,-13,13]},{"box":[-31.4,31.4,12.4,32,-13,13]}],"mounts":[{"cyl":"y","r":2.75,"span":["-",0],"at":[0,0],"copies":[[-27.94,0,-9.525],[27.94,0,-9.525],[-27.94,0,9.525],[27.94,0,9.525]]}],"cuts":[{"cyl":"y","r":1.05,"span":[0.1,-3],"at":[0,0],"copies":[[-27.94,0,-9.525],[27.94,0,-9.525],[-27.94,0,9.525],[27.94,0,9.525]]}],"pieces":[],"provides":[{"id":"pwm","kind":"pwm","count":16,"note":"12-bit PWM, 40-1000 Hz, one 3-pin servo header per channel along both long edges (GND/VCC/signal)"}],"power":"5 V VCC on the I2C header; servo power comes from the same VCC rail","wiring":{"needs":[{"kind":"i2c","count":1,"note":"VCC 5 V, GND, SCL, SDA; A0-A5 solder jumpers pick the address 0x40-0x7F"}],"cable":"4-pin header to the brain's I2C port; up to 16 servo leads on the board's own headers"},"mass_g":null,"current_ma":null},"scs0009-joint-posts":{"id":"scs0009-joint-posts","title":"Joint (SCS0009 bus servo) on posts","kind":"bought","buy":"Feetech SCS0009 bus servo, 2-pack","frame":"origin = on the spline axis at the top of the cover; -Y = the spline (the moving side); +Z up; the case centre is 5.7 mm from the spline along +X. This is the same servo on three posts instead of a flange plate: the posts grow from under the flange tabs and the case bottom along +Y to the body skin behind it, so a servo whose spline points up (a pan joint on a base floor) prints with no support. Screws go down through the flange holes into the posts.","size":[23.2,25.25,12.1],"sources":["Feetech SCS0009 spec A/0 (research_notes/2026-11-02-R9-facts-closure.md section 3): 23.2 x 12.1 x 25.25, over flanges 32.5, holes 28.5 apart O2, spline 5.7 from the case centre, 20T 3.95, spline 3.2 above the cover, 13.2 g, stall 2.3 kg.cm and 1.0 A at 6 V, rated 0.75 kg.cm, 0.1 s/60 deg, 300 deg","posts instead of the plate: same flange tab and hole positions as scs0009-joint (BAB-0044, 2026-11-03)"],"measure":["flange levels (16.8..18.4 from the bottom assumed) and tab width (11)","horn: shape and size (disc 21 x 1.5 assumed); 20T or 25T spline on the batch we get"],"seat":["-z",10],"standin":{"add":[{"box":[-5.9,17.3,0,25.25,-6.05,6.05]},{"box":[-10.55,21.95,6.85,8.45,-5.5,5.5]},{"cyl":"y","r":1.975,"span":[-3.2,0],"at":[0,0]},{"cyl":"y","r":10.5,"span":[-4.7,-3.2],"at":[0,0]}],"cut":[]},"keepout":[{"box":[-6.1,17.5,-0.2,25.45,-6.25,6.25]},{"box":[-10.75,22.15,6.65,8.65,-5.7,5.7]}],"mounts":[{"box":[-13,-6.1,8.55,"+",-4.5,4.5]},{"box":[17.5,24.5,8.55,"+",-4.5,4.5]},{"box":[-5,16,25.45,"+",-4,4]}],"cuts":[{"cyl":"y","r":0.8,"span":[8.45,16],"at":[-8.55,0],"copies":[[0,0,0],[28.5,0,0]]}],"joint":{"axis":"-y","at":[0,0,0],"range_deg":[-150,150],"stall_kgcm":2.3,"rated_kgcm":0.75,"speed_s_per_60deg":0.1,"volts":6,"moving":{"seat":["-y",3],"note":"the moving body's skin sits 3.0 mm out from the cover (seat); the horn sits in a recess in it, the boss (square, so its sides print as short flat ledges) gives 1.8 mm or more round the recess; the horn screw hole runs out through the moving body (up to 25 mm thick) so a driver reaches it","keepout":[{"cyl":"y","r":11.2,"span":[-5,0.2],"at":[0,0]}],"mounts":[{"box":[-12.5,12.5,-9,-3.2,-12.5,12.5]}],"cuts":[{"cyl":"y","r":10.7,"span":[-4.9,-3],"at":[0,0],"tearUp":true},{"cyl":"y","r":1.2,"span":[-30,-4.8],"at":[0,0],"tearUp":true}]}},"pieces":[],"wiring":{"needs":[{"kind":"servo-bus","count":1}],"cable":"3-wire bus lead, daisy-chained; needs a bus servo driver on the brain's serial pins"},"mass_g":13.2,"current_ma":{"stall":1000,"volts":6}},"scs0009-joint":{"id":"scs0009-joint","title":"Joint (SCS0009 bus servo)","kind":"bought","buy":"Feetech SCS0009 bus servo, 2-pack","frame":"origin = on the spline axis at the top of the cover; -Y = the spline (the moving side); +Z up; the case centre is 5.7 mm from the spline along +X","size":[23.2,25.25,12.1],"sources":["Feetech SCS0009 spec A/0 (research_notes/2026-11-02-R9-facts-closure.md section 3): 23.2 x 12.1 x 25.25, over flanges 32.5, holes 28.5 apart O2, spline 5.7 from the case centre, 20T 3.95, spline 3.2 above the cover, 13.2 g, stall 2.3 kg.cm and 1.0 A at 6 V, rated 0.75 kg.cm, 0.1 s/60 deg, 300 deg"],"measure":["flange levels (16.8..18.4 from the bottom assumed) and tab width (11)","horn: shape and size (disc 21 x 1.5 assumed); 20T or 25T spline on the batch we get"],"seat":["-z",10],"standin":{"add":[{"box":[-5.9,17.3,0,25.25,-6.05,6.05]},{"box":[-10.55,21.95,6.85,8.45,-5.5,5.5]},{"cyl":"y","r":1.975,"span":[-3.2,0],"at":[0,0]},{"cyl":"y","r":10.5,"span":[-4.7,-3.2],"at":[0,0]}],"cut":[]},"keepout":[{"box":[-6.1,17.5,-0.2,25.45,-6.25,6.25]},{"box":[-10.75,22.15,6.65,8.65,-5.7,5.7]}],"mounts":[{"box":[-13,24.5,8.55,12.05,"-",8]},{"box":[-5,16,21,25,"-",-6.3]}],"cuts":[{"box":[-6.25,17.65,8.45,12.15,-6.25,9]},{"cyl":"y","r":0.8,"span":[8.45,12.15],"at":[-8.55,0],"copies":[[0,0,0],[28.5,0,0]]}],"joint":{"axis":"-y","at":[0,0,0],"range_deg":[-150,150],"stall_kgcm":2.3,"rated_kgcm":0.75,"speed_s_per_60deg":0.1,"volts":6,"moving":{"seat":["-y",3],"note":"the moving body's skin sits 3.0 mm out from the cover (seat); the horn sits in a recess in it, the boss (square, so its sides print as short flat ledges) gives 1.8 mm or more round the recess; the horn screw hole runs out through the moving body (up to 25 mm thick) so a driver reaches it","keepout":[{"cyl":"y","r":11.2,"span":[-5,0.2],"at":[0,0]}],"mounts":[{"box":[-12.5,12.5,-9,-3.2,-12.5,12.5]}],"cuts":[{"cyl":"y","r":10.7,"span":[-4.9,-3],"at":[0,0],"tearUp":true},{"cyl":"y","r":1.2,"span":[-30,-4.8],"at":[0,0],"tearUp":true}]}},"pieces":[],"wiring":{"needs":[{"kind":"servo-bus","count":1}],"cable":"3-wire bus lead, daisy-chained; needs a bus servo driver on the brain's serial pins"},"mass_g":13.2,"current_ma":{"stall":1000,"volts":6}},"snap-hook":{"id":"snap-hook","title":"Snap hook and its window","kind":"fixing","mirror":true,"buy":"nothing: printed in the two pieces it joins","frame":"origin = on the wall's inner face at the seam (the rim of the piece that carries the hook), middle of the hook; +X = out through the wall; +Y = into the other piece; +Z = along the wall. The hook goes on `piece`, the window on `other`. Mirror it in X for the opposite wall.","sources":["parts/bots/mini.py head_bezel / head_tub: PETG cantilever L 8, t 1.6, undercut 0.6, catch outward; window 2 x 6.4"],"measure":["snap force and fatigue in real PETG (print one and click it 50 times)"],"seat":["+x",2],"standin":{"add":[],"cut":[]},"keepout":[],"mounts":[{"box":[-1.8,-0.2,0,7.5,-3,3]},{"box":[-0.2,0.4,5.2,6.8,-3,3]},{"box":[-1.8,0.5,-2,0,-3,3]}],"cuts":[],"other":{"cuts":[{"box":[-0.5,2.5,5,7,-3.2,3.2]}]},"pieces":[],"wiring":{"needs":[]}},"speaker-1217":{"id":"speaker-1217","title":"Speaker 1217","kind":"bought","buy":"comes with the Waveshare ESP32-S3-CAM-OV5640 board","frame":"origin = centre of the sound face; -Y = where the sound goes (through the grille); 17 wide (x), 12 tall (z), 4 deep (y)","size":[17,4,12],"sources":["research_notes/2026-11-02-R9-facts-closure.md 1d (speaker in the board's box)","parts/bots/mini.py head: cradle rib, grille slots"],"measure":["size (17 x 12 x 4 assumed from the 1217 name)","mass"],"seat":["-y",3],"standin":{"add":[{"box":[-8.5,8.5,0,4,-6,6]}],"cut":[]},"keepout":[{"box":[-8.7,8.7,-0.2,4.2,-6.2,6.2]}],"mounts":[{"box":[-9,"+",4.2,5.4,-6.5,6.5]}],"cuts":[{"box":[-7.5,5.5,-3.6,-0.5,-4.5,-3],"copies":[[0,0,0],[0,0,2.8],[0,0,5.6],[0,0,8.4]]}],"pieces":[],"rules":{"note":"grille slots run up the print (1.3 mm bars, 1.5 mm slots)"},"wiring":{"needs":[{"kind":"speaker","count":1}],"cable":"2-pin to the brain's speaker port"},"mass_g":null,"current_ma":null},"speaker-40mm":{"id":"speaker-40mm","title":"Speaker 40 mm","kind":"bought","buy":"Adafruit 40 mm speaker, product 3968","frame":"origin = centre of the sound face; -Y = where the sound goes (through the grille); the cone faces -Y, the magnet cap (r 10) and the solder tabs face +Y, so the plug room for the cable runs to y 45.3; O40 x 25 deep","size":[40,25,40],"sources":["parts/vendor/measured/3968_speaker_40mm.json (measured from parts/vendor/adafruit-cad-parts/3968_speaker_40mm.step, Adafruit MIT): size [40, 40, 25] cylinder r 20; cone r 18 / 15.5 / 14.5 at z 0..1.5 (front), magnet cap r 10 at z 25 (back); 16 x r 1.0 tab holes in two rings at z 10 and z 14, radius 11.3-12.0 — inside the r 20 basket, so they cannot take posts from a pocket wall; a cradle plate holds the back instead","research_notes/2026-11-02-R3-brains-sensors-screens-audio.md:206: Adafruit 3968 speaker 40 mm, O40 x 25 mm deep (model), rear tabs, Adafruit STEP (MIT); https://github.com/adafruit/Adafruit_CAD_Parts (MIT)","shared/recipes/speaker-1217.json: part behind a wall with grille slots, seat -y"],"measure":["mass (not in the measured STEP or the product page)","solder tab position on the back cap (plug room assumed 20 mm out from the back face)"],"seat":["-y",3],"standin":{"add":[{"cyl":"y","r":20,"span":[0,25],"at":[0,0]}],"cut":[]},"keepout":[{"cyl":"y","r":20.3,"span":[-0.2,25.3],"at":[0,0]},{"cyl":"y","r":8,"span":[25.3,45.3],"at":[0,0]}],"mounts":[{"box":[12,17,25.3,"+",-2.5,2.5]},{"box":[-17,-12,25.3,"+",-2.5,2.5]},{"box":[-2.5,2.5,25.3,"+",12,17]},{"box":[-2.5,2.5,25.3,"+",-17,-12]}],"cuts":[{"box":[-13,13,-3.5,-0.1,-1,1],"copies":[[0,0,0],[0,0,6],[0,0,-6],[0,0,12],[0,0,-12]]}],"pieces":[],"rules":{"note":"grille slots run up the print (2.0 mm slots, 4 mm bars, kept inside the r 18 cone)"},"wiring":{"needs":[{"kind":"speaker","count":1}],"cable":"2-wire cable from the back solder tabs to the amp's speaker terminal"},"mass_g":null,"current_ma":null}},"kits":[{"id":"ears-cat","title":"Cat ears","group":"Ears","about":"Two pointed ears, leaning out a little, each with a pocket for the inner ear.","face":"top","ref":60,"place":[0,0],"shapes":[{"prism":"y","pts":[[-26,-1.5],[-9,-1.5],[-23.4,19],[-25.4,19]],"span":[-4,4],"fill":true,"name":"Cat ear"},{"prism":"y","pts":[[26,-1.5],[9,-1.5],[23.4,19],[25.4,19]],"span":[-4,4],"fill":true,"name":"Cat ear"},{"prism":"y","pts":[[-23,3],[-15.5,3],[-22.5,13]],"span":[-6,-2.5],"hole":true,"name":"Inner ear"},{"prism":"y","pts":[[23,3],[15.5,3],[22.5,13]],"span":[-6,-2.5],"hole":true,"name":"Inner ear"}]},{"id":"ears-bunny","title":"Bunny ears","group":"Ears","about":"Two long rounded ears, leaning out. Needs head room: they are 34 mm tall.","face":"top","ref":60,"place":[0,0],"shapes":[{"prism":"y","pts":[[-17.5,-1.5],[-21.5,29.5],[-21.28,30.891],[-20.641,32.145],[-19.645,33.141],[-18.391,33.78],[-17,34],[-15.609,33.78],[-14.355,33.141],[-13.359,32.145],[-12.72,30.891],[-12.5,29.5],[-8.5,-1.5]],"span":[-3.5,3.5],"fill":true,"name":"Bunny ear"},{"prism":"y","pts":[[17.5,-1.5],[21.5,29.5],[21.28,30.891],[20.641,32.145],[19.645,33.141],[18.391,33.78],[17,34],[15.609,33.78],[14.355,33.141],[13.359,32.145],[12.72,30.891],[12.5,29.5],[8.5,-1.5]],"span":[-3.5,3.5],"fill":true,"name":"Bunny ear"}]},{"id":"ears-bear","title":"Bear ears","group":"Ears","about":"Two round ears on the top corners.","face":"top","ref":60,"place":[0,0],"shapes":[{"rev":"z","pts":[[0,-1.5],[9,-1.5],[9,0.5],[8.889,1.751],[8.56,2.972],[8.019,4.132],[7.281,5.202],[6.364,6.157],[5.29,6.972],[4.086,7.628],[2.781,8.108],[1.408,8.402],[0,8.5]],"at":[-25,0],"fill":true,"name":"Bear ear"},{"rev":"z","pts":[[0,-1.5],[9,-1.5],[9,0.5],[8.889,1.751],[8.56,2.972],[8.019,4.132],[7.281,5.202],[6.364,6.157],[5.29,6.972],[4.086,7.628],[2.781,8.108],[1.408,8.402],[0,8.5]],"at":[25,0],"fill":true,"name":"Bear ear"}]},{"id":"antenna-ball","title":"Antenna with bulb","group":"Antennas","about":"One thin rod with a bulb on the end. The bulb widens at 45 degrees under the round top.","face":"top","ref":60,"place":[0,0],"shapes":[{"rev":"z","pts":[[0,-1.5],[3.6,-1.5],[3.6,2.5],[1.6,2.5],[1.6,18],[4.5,20.9],[4.445,21.534],[4.28,22.152],[4.01,22.739],[3.641,23.281],[3.182,23.764],[2.645,24.177],[2.043,24.509],[1.391,24.752],[0.704,24.9],[0,24.95]],"at":[0,0],"fill":true,"name":"Antenna"}]},{"id":"antenna-twin","title":"Twin antennas","group":"Antennas","about":"Two thin rods with small bulbs.","face":"top","ref":60,"place":[0,0],"shapes":[{"rev":"z","pts":[[0,-1.5],[3.6,-1.5],[3.6,2.5],[1.4,2.5],[1.4,22],[3.4,24],[3.358,24.479],[3.234,24.946],[3.029,25.389],[2.751,25.799],[2.404,26.164],[1.998,26.476],[1.544,26.726],[1.051,26.91],[0.532,27.022],[0,27.06]],"at":[-14,0],"fill":true,"name":"Antenna L"},{"rev":"z","pts":[[0,-1.5],[3.6,-1.5],[3.6,2.5],[1.4,2.5],[1.4,22],[3.4,24],[3.358,24.479],[3.234,24.946],[3.029,25.389],[2.751,25.799],[2.404,26.164],[1.998,26.476],[1.544,26.726],[1.051,26.91],[0.532,27.022],[0,27.06]],"at":[14,0],"fill":true,"name":"Antenna R"}]},{"id":"horns","title":"Little horns","group":"Ears","about":"Two short cones, like a small devil.","face":"top","ref":60,"place":[0,0],"shapes":[{"cone":"z","r0":6,"r1":1.3,"span":[-1.5,16],"at":[-20,0],"fill":true,"name":"Horn"},{"cone":"z","r0":6,"r1":1.3,"span":[-1.5,16],"at":[20,0],"fill":true,"name":"Horn"}]},{"id":"crest","title":"Crest","group":"Ears","about":"A row of five pointed fins, tall in the middle.","face":"top","ref":60,"place":[0,0],"shapes":[{"prism":"y","pts":[[-24.5,-1.5],[-15.5,-1.5],[-18.8,9],[-21.2,9]],"span":[-3.5,3.5],"fill":true,"name":"Crest fin"},{"prism":"y","pts":[[-14.5,-1.5],[-5.5,-1.5],[-8.8,13],[-11.2,13]],"span":[-3.5,3.5],"fill":true,"name":"Crest fin"},{"prism":"y","pts":[[-4.5,-1.5],[4.5,-1.5],[1.2,18],[-1.2,18]],"span":[-3.5,3.5],"fill":true,"name":"Crest fin"},{"prism":"y","pts":[[5.5,-1.5],[14.5,-1.5],[11.2,13],[8.8,13]],"span":[-3.5,3.5],"fill":true,"name":"Crest fin"},{"prism":"y","pts":[[15.5,-1.5],[24.5,-1.5],[21.2,9],[18.8,9]],"span":[-3.5,3.5],"fill":true,"name":"Crest fin"}]},{"id":"handle","title":"Carry handle","group":"Handles","about":"A tent-shaped handle you can hook a finger under. Every slope is 45 degrees.","face":"top","ref":60,"place":[0,0],"shapes":[{"prism":"y","pts":[[-20,-1.5],[-20,6],[-5,21],[5,21],[20,6],[20,-1.5],[13,-1.5],[13,8],[3,18],[-3,18],[-13,8],[-13,-1.5]],"span":[-4,4],"fill":true,"name":"Handle"}]},{"id":"halo-ring","title":"Halo ring","group":"Rings and lights","about":"A thin ring that sits on the top like a halo or a light ring.","face":"top","ref":60,"place":[0,0],"refV":28,"shapes":[{"ring":"z","R":10,"r":2.2,"at":[0,0],"along":0,"fill":true,"name":"Halo ring"}]},{"id":"vents-round","title":"Round vents","group":"Vents and grilles","about":"Seven round holes in a flower pattern.","face":"top","ref":60,"place":[0,0],"shapes":[{"cyl":"z","r":2,"span":[-7,1.2],"at":[0,0],"copies":[[0,0,0],[6.5,0,0],[3.25,5.629,0],[-3.25,5.629,0],[-6.5,0,0],[-3.25,-5.629,0],[3.25,-5.629,0]],"hole":true,"name":"Round vents"}]},{"id":"visor-brow","title":"Angry brows","group":"Face","about":"Two slanted brow bars above the screen.","face":"front","ref":60,"place":[0,0.6],"shapes":[{"prism":"z","pts":[[-28,3],[-8,-3],[-8,2.5],[-28,8.5]],"span":[-1.5,4],"fill":true,"name":"Brow"},{"prism":"z","pts":[[28,3],[8,-3],[8,2.5],[28,8.5]],"span":[-1.5,4],"fill":true,"name":"Brow"}]},{"id":"visor-hood","title":"Visor hood","group":"Face","about":"A brim across the top of the face that keeps the glare off the screen. The underside slopes 45 degrees.","face":"front","ref":60,"place":[0,0.7],"shapes":[{"prism":"x","pts":[[-8,-1.5],[-8,0],[4,12],[8,12],[8,-1.5]],"span":[-30,30],"fill":true,"name":"Visor"}]},{"id":"chin","title":"Chin","group":"Face","about":"A rounded lip along the bottom of the face.","face":"front","ref":60,"place":[0,-1],"shapes":[{"prism":"z","pts":[[15,1],[16.545,1.245],[17.939,1.955],[19.045,3.061],[19.755,4.455],[20,6],[19.755,7.545],[19.045,8.939],[17.939,10.045],[16.545,10.755],[15,11],[-15,11],[-16.545,10.755],[-17.939,10.045],[-19.045,8.939],[-19.755,7.545],[-20,6],[-19.755,4.455],[-19.045,3.061],[-17.939,1.955],[-16.545,1.245],[-15,1]],"span":[-1.5,5],"fill":true,"name":"Chin"}]},{"id":"cheek-pods","title":"Cheek pods","group":"Face","about":"Two low round pods on the cheeks.","face":"front","ref":60,"place":[0,-0.3],"refV":20,"shapes":[{"rev":"z","pts":[[0,-1.5],[7.5,-1.5],[7.5,0],[7.408,0.782],[7.133,1.545],[6.683,2.27],[6.068,2.939],[5.303,3.536],[4.408,4.045],[3.405,4.455],[2.318,4.755],[1.173,4.938],[0,5]],"at":[-24,0],"fill":true,"name":"Cheek pod"},{"rev":"z","pts":[[0,-1.5],[7.5,-1.5],[7.5,0],[7.408,0.782],[7.133,1.545],[6.683,2.27],[6.068,2.939],[5.303,3.536],[4.408,4.045],[3.405,4.455],[2.318,4.755],[1.173,4.938],[0,5]],"at":[24,0],"fill":true,"name":"Cheek pod"}]},{"id":"eye-rings","title":"Eye rings","group":"Face","about":"Two raised rings with a round pupil in each: eyes without a screen.","face":"front","ref":60,"place":[0,0.1],"refV":24,"shapes":[{"ring":"z","R":8,"r":1.8,"at":[-14,0],"along":0.2,"fill":true,"name":"Eye ring"},{"ring":"z","R":8,"r":1.8,"at":[14,0],"along":0.2,"fill":true,"name":"Eye ring"},{"rev":"z","pts":[[0,-1.5],[3.8,-1.5],[3.8,0],[3.753,0.469],[3.614,0.927],[3.386,1.362],[3.074,1.763],[2.687,2.121],[2.234,2.427],[1.725,2.673],[1.174,2.853],[0.594,2.963],[0,3]],"at":[-14,0],"fill":true,"name":"Pupil"},{"rev":"z","pts":[[0,-1.5],[3.8,-1.5],[3.8,0],[3.753,0.469],[3.614,0.927],[3.386,1.362],[3.074,1.763],[2.687,2.121],[2.234,2.427],[1.725,2.673],[1.174,2.853],[0.594,2.963],[0,3]],"at":[14,0],"fill":true,"name":"Pupil"}]},{"id":"armour-chest","title":"Chest plate","group":"Armour and bumpers","about":"A chamfered plate with a raised V stripe.","face":"front","ref":60,"place":[0,-0.1],"shapes":[{"prism":"z","pts":[[-26,-12],[26,-12],[30,-8],[30,8],[26,12],[-26,12],[-30,8],[-30,-8]],"span":[-1.5,3.5],"fill":true,"name":"Chest plate"},{"prism":"z","pts":[[-18,4],[0,-4],[18,4],[18,9],[0,1],[-18,9]],"span":[3,6],"fill":true,"name":"V stripe"}]},{"id":"bumper","title":"Bumper","group":"Armour and bumpers","about":"A chamfered bar along the bottom edge. Both slopes are 45 degrees.","face":"front","ref":60,"place":[0,-1],"shapes":[{"prism":"x","pts":[[1,-1.5],[1,3],[4,6],[6,6],[9,3],[9,-1.5]],"span":[-30,30],"fill":true,"name":"Bumper"}]},{"id":"badge-star","title":"Star badge","group":"Rings and lights","about":"A round badge with a raised star.","face":"front","ref":60,"place":[0.6,0.5],"refV":24,"shapes":[{"cyl":"z","r":10,"span":[-1.5,2.5],"at":[0,0],"fill":true,"name":"Badge"},{"prism":"z","pts":[[0,7.5],[-2.292,3.155],[-7.133,2.318],[-3.709,-1.205],[-4.408,-6.068],[0,-3.9],[4.408,-6.068],[3.709,-1.205],[7.133,2.318],[2.292,3.155]],"span":[2.2,5],"fill":true,"name":"Badge star"}]},{"id":"grille-slats","title":"Louvre slots","group":"Vents and grilles","about":"Seven narrow upright slots, like a radiator.","face":"front","ref":60,"place":[0,-0.45],"shapes":[{"box":[-15,-12.8,-9,9,-7,1.2],"copies":[[0,0,0],[5,0,0],[10,0,0],[15,0,0],[20,0,0],[25,0,0],[30,0,0]],"hole":true,"name":"Louvre slots"}]},{"id":"vents-side","title":"Side vents","group":"Vents and grilles","about":"Five horizontal slots in a stack.","face":"left","ref":60,"place":[0,0],"shapes":[{"box":[-13,13,-10,-7.8,-7,1.2],"copies":[[0,0,0],[0,5,0],[0,10,0],[0,15,0],[0,20,0]],"hole":true,"name":"Side vents"}]},{"id":"grille-dots","title":"Speaker grille","group":"Vents and grilles","about":"A square of small round holes for a speaker behind it.","face":"left","ref":60,"place":[0,0],"shapes":[{"cyl":"z","r":1.3,"span":[-7,1.2],"at":[-6.75,-6.75],"copies":[[0,0,0],[4.5,0,0],[9,0,0],[13.5,0,0],[0,4.5,0],[4.5,4.5,0],[9,4.5,0],[13.5,4.5,0],[0,9,0],[4.5,9,0],[9,9,0],[13.5,9,0],[0,13.5,0],[4.5,13.5,0],[9,13.5,0],[13.5,13.5,0]],"hole":true,"name":"Speaker grille"}]},{"id":"back-fin","title":"Back fin","group":"Fins and tails","about":"A swept fin up the back, like a shark.","face":"back","ref":60,"place":[0,0],"shapes":[{"prism":"x","pts":[[-14,-1.5],[16,-1.5],[16,4],[0,20],[-4,20]],"span":[-3,3],"fill":true,"name":"Back fin"}]},{"id":"armour-hex","title":"Hex plates","group":"Armour and bumpers","about":"Three hexagon tiles side by side, like honeycomb.","face":"back","ref":60,"place":[0,0],"refV":48,"shapes":[{"prism":"z","pts":[[-0.473,9.25],[-8.7,14],[-16.927,9.25],[-16.927,-0.25],[-8.7,-5],[-0.473,-0.25]],"span":[-1.5,3],"fill":true,"name":"Hex plate"},{"prism":"z","pts":[[16.927,9.25],[8.7,14],[0.473,9.25],[0.473,-0.25],[8.7,-5],[16.927,-0.25]],"span":[-1.5,3],"fill":true,"name":"Hex plate"},{"prism":"z","pts":[[8.227,-5.85],[0,-1.1],[-8.227,-5.85],[-8.227,-15.35],[0,-20.1],[8.227,-15.35]],"span":[-1.5,3],"fill":true,"name":"Hex plate"}]},{"id":"tail","title":"Tail","group":"Fins and tails","about":"A short tapered tail with a round tip.","face":"back","ref":60,"place":[0,-0.3],"shapes":[{"rev":"z","pts":[[0,-1.5],[6,-1.5],[2.4,22],[2.37,22.469],[2.283,22.927],[2.138,23.362],[1.942,23.763],[1.697,24.121],[1.411,24.427],[1.09,24.673],[0.742,24.853],[0.375,24.963],[0,25]],"at":[0,0],"fill":true,"name":"Tail"}]},{"id":"feet-round","title":"Round feet","group":"Feet","about":"Four round feet, one near each corner.","face":"bottom","ref":60,"place":[0,0],"refV":44,"shapes":[{"cyl":"z","r":6,"span":[-1.5,6],"at":[-22,-16],"fill":true,"name":"Foot"},{"cyl":"z","r":6,"span":[-1.5,6],"at":[22,-16],"fill":true,"name":"Foot"},{"cyl":"z","r":6,"span":[-1.5,6],"at":[-22,16],"fill":true,"name":"Foot"},{"cyl":"z","r":6,"span":[-1.5,6],"at":[22,16],"fill":true,"name":"Foot"}]},{"id":"feet-skid","title":"Skids","group":"Feet","about":"Two long rounded skids for sliding.","face":"bottom","ref":60,"place":[0,0],"refV":58,"shapes":[{"prism":"z","pts":[[-27,21],[-26.755,22.545],[-26.045,23.939],[-24.939,25.045],[-23.545,25.755],[-22,26],[-20.455,25.755],[-19.061,25.045],[-17.955,23.939],[-17.245,22.545],[-17,21],[-17,-21],[-17.245,-22.545],[-17.955,-23.939],[-19.061,-25.045],[-20.455,-25.755],[-22,-26],[-23.545,-25.755],[-24.939,-25.045],[-26.045,-23.939],[-26.755,-22.545],[-27,-21]],"span":[-1.5,5],"fill":true,"name":"Skid"},{"prism":"z","pts":[[27,21],[26.755,22.545],[26.045,23.939],[24.939,25.045],[23.545,25.755],[22,26],[20.455,25.755],[19.061,25.045],[17.955,23.939],[17.245,22.545],[17,21],[17,-21],[17.245,-22.545],[17.955,-23.939],[19.061,-25.045],[20.455,-25.755],[22,-26],[23.545,-25.755],[24.939,-25.045],[26.045,-23.939],[26.755,-22.545],[27,-21]],"span":[-1.5,5],"fill":true,"name":"Skid"}]},{"id":"feet-claw","title":"Claw feet","group":"Feet","about":"Two flat feet, each with three toes.","face":"bottom","ref":60,"place":[0,0],"refV":40,"shapes":[{"prism":"z","pts":[[-26,-3],[-10,-3],[-10,11],[-26,11]],"span":[-1.5,4.5],"fill":true,"name":"Foot"},{"prism":"z","pts":[[26,-3],[10,-3],[10,11],[26,11]],"span":[-1.5,4.5],"fill":true,"name":"Foot"},{"prism":"z","pts":[[-26.1,-1.5],[-20.9,-1.5],[-22,-13],[-25,-13]],"span":[-1.5,4.5],"fill":true,"name":"Toe"},{"prism":"z","pts":[[26.1,-1.5],[20.9,-1.5],[22,-13],[25,-13]],"span":[-1.5,4.5],"fill":true,"name":"Toe"},{"prism":"z","pts":[[-20.6,-1.5],[-15.4,-1.5],[-16.5,-13],[-19.5,-13]],"span":[-1.5,4.5],"fill":true,"name":"Toe"},{"prism":"z","pts":[[20.6,-1.5],[15.4,-1.5],[16.5,-13],[19.5,-13]],"span":[-1.5,4.5],"fill":true,"name":"Toe"},{"prism":"z","pts":[[-15.1,-1.5],[-9.9,-1.5],[-11,-13],[-14,-13]],"span":[-1.5,4.5],"fill":true,"name":"Toe"},{"prism":"z","pts":[[15.1,-1.5],[9.9,-1.5],[11,-13],[14,-13]],"span":[-1.5,4.5],"fill":true,"name":"Toe"}]}],"starters":[{"id":"pod","title":"Pod","about":"A fat, round-cornered head: the screen face, a camera above it and a speaker in the side. Sits on its flat bottom.","bodies":[{"id":"head","at":[0,0,0],"wall":2,"shapes":[{"rrect":"y","w":80,"h":76,"r":24,"span":[0,31.6],"at":[0,38],"name":"Pod shell"},{"hole":true,"box":[-44,-32,13,26,38.45,39.95],"copies":[[0,0,0],[0,0,2.8],[0,0,5.6],[0,0,8.4]]},{"hole":true,"tear":"z","r":5,"span":[-0.1,2.1],"at":[0,18],"tip":"-y"}],"seams":[{"axis":"y","at":4,"band":1.6}],"pieces":[{"id":"head-bezel","title":"Face bezel","material":"PETG","colour":"teal","print":"y_front_down"},{"id":"head-seam","title":"Head light seam","material":"PETG clear","colour":"glow","print":"y_front_down"},{"id":"head-tub","title":"Head shell","material":"PETG","colour":"white","print":"y_back_down"}],"parts":[{"recipe":"lcd-2in","name":"screen","at":[0,3.5,30]},{"recipe":"cam-board","name":"brain","at":[0,25.6,30],"turn":[[0,0,180]]},{"recipe":"camera-ov5640","name":"camera","at":[0,3.6,55.95]},{"recipe":"speaker-1217","name":"speaker","at":[37,20.5,42.95],"turn":[[0,0,90]]},{"recipe":"snap-hook","name":"hook-r0","at":[38,4,25],"piece":"head-bezel","other":"head-tub"},{"recipe":"snap-hook","name":"hook-l0","at":[-38,4,25],"mirror":"x","piece":"head-bezel","other":"head-tub"},{"recipe":"snap-hook","name":"hook-r1","at":[38,4,35],"piece":"head-bezel","other":"head-tub"},{"recipe":"snap-hook","name":"hook-l1","at":[-38,4,35],"mirror":"x","piece":"head-bezel","other":"head-tub"}],"title":"Pod"}]},{"id":"cube-bot","title":"Cube bot","about":"A square, deeper head with tight corners. Same screen, camera and speaker as every bot, more room inside.","bodies":[{"id":"head","at":[0,0,0],"wall":2,"shapes":[{"rrect":"y","w":72,"h":72,"r":5,"span":[0,40],"at":[0,36],"name":"Cube bot shell"},{"hole":true,"box":[-40,-28,13,26,36.45,37.95],"copies":[[0,0,0],[0,0,2.8],[0,0,5.6],[0,0,8.4]]},{"hole":true,"tear":"z","r":5,"span":[-0.1,2.1],"at":[0,18],"tip":"-y"}],"seams":[{"axis":"y","at":4,"band":1.6}],"pieces":[{"id":"head-bezel","title":"Face bezel","material":"PETG","colour":"orange","print":"y_front_down"},{"id":"head-seam","title":"Head light seam","material":"PETG clear","colour":"glow","print":"y_front_down"},{"id":"head-tub","title":"Head shell","material":"PETG","colour":"graphite","print":"y_back_down"}],"parts":[{"recipe":"lcd-2in","name":"screen","at":[0,3.5,28]},{"recipe":"cam-board","name":"brain","at":[0,25.6,28],"turn":[[0,0,180]]},{"recipe":"camera-ov5640","name":"camera","at":[0,3.6,53.95]},{"recipe":"speaker-1217","name":"speaker","at":[33,20.5,40.95],"turn":[[0,0,90]]},{"recipe":"snap-hook","name":"hook-r0","at":[34,4,23],"piece":"head-bezel","other":"head-tub"},{"recipe":"snap-hook","name":"hook-l0","at":[-34,4,23],"mirror":"x","piece":"head-bezel","other":"head-tub"},{"recipe":"snap-hook","name":"hook-r1","at":[34,4,33],"piece":"head-bezel","other":"head-tub"},{"recipe":"snap-hook","name":"hook-l1","at":[-34,4,33],"mirror":"x","piece":"head-bezel","other":"head-tub"}],"title":"Cube bot"}]},{"id":"egg-bot","title":"Egg bot","about":"An egg-shaped face, wide at the bottom: the screen sits low and the camera in the narrow top.","bodies":[{"id":"head","at":[0,0,0],"wall":2,"shapes":[{"prism":"y","pts":[[0,-11],[7.261,-10.857],[12.323,-10.426],[16.714,-9.711],[20.648,-8.711],[24.204,-7.429],[27.417,-5.867],[30.304,-4.029],[32.873,-1.917],[35.129,0.467],[37.074,3.122],[38.711,6.048],[40.045,9.25],[41.078,12.738],[41.818,16.533],[42.271,20.676],[42.445,25.255],[42.351,30.5],[42,38],[41.403,45.5],[40.571,50.745],[39.519,55.324],[38.258,59.467],[36.8,63.262],[35.157,66.75],[33.339,69.952],[31.356,72.878],[29.214,75.533],[26.919,77.917],[24.471,80.029],[21.868,81.867],[19.102,83.429],[16.153,84.711],[12.985,85.711],[9.525,86.426],[5.596,86.857],[0,87],[-5.596,86.857],[-9.525,86.426],[-12.985,85.711],[-16.153,84.711],[-19.102,83.429],[-21.868,81.867],[-24.471,80.029],[-26.919,77.917],[-29.214,75.533],[-31.356,72.878],[-33.339,69.952],[-35.157,66.75],[-36.8,63.262],[-38.258,59.467],[-39.519,55.324],[-40.571,50.745],[-41.403,45.5],[-42,38],[-42.351,30.5],[-42.445,25.255],[-42.271,20.676],[-41.818,16.533],[-41.078,12.738],[-40.045,9.25],[-38.711,6.048],[-37.074,3.122],[-35.129,0.467],[-32.873,-1.917],[-30.304,-4.029],[-27.417,-5.867],[-24.204,-7.429],[-20.648,-8.711],[-16.714,-9.711],[-12.323,-10.426],[-7.261,-10.857]],"span":[0,31.6],"name":"Egg bot shell"},{"hole":true,"box":[-45.80498,-33.80498,13,26,36.45,37.95],"copies":[[0,0,0],[0,0,2.8],[0,0,5.6],[0,0,8.4]]},{"hole":true,"tear":"z","r":5,"span":[-0.1,2.1],"at":[0,18],"tip":"-y"}],"seams":[{"axis":"y","at":4,"band":1.6}],"pieces":[{"id":"head-bezel","title":"Face bezel","material":"PETG","colour":"bone","print":"y_front_down"},{"id":"head-seam","title":"Head light seam","material":"PETG clear","colour":"glow","print":"y_front_down"},{"id":"head-tub","title":"Head shell","material":"PETG","colour":"magenta","print":"y_back_down"}],"parts":[{"recipe":"lcd-2in","name":"screen","at":[0,3.5,28]},{"recipe":"cam-board","name":"brain","at":[0,25.6,28],"turn":[[0,0,180]]},{"recipe":"camera-ov5640","name":"camera","at":[0,3.6,53.95]},{"recipe":"speaker-1217","name":"speaker","at":[38.765,20.5,40.95],"turn":[[0,0,90]]},{"recipe":"snap-hook","name":"hook-r0","at":[40.432,4,26],"piece":"head-bezel","other":"head-tub"},{"recipe":"snap-hook","name":"hook-l0","at":[-40.432,4,26],"mirror":"x","piece":"head-bezel","other":"head-tub"},{"recipe":"snap-hook","name":"hook-r1","at":[40.094,4,36],"piece":"head-bezel","other":"head-tub"},{"recipe":"snap-hook","name":"hook-l1","at":[-40.094,4,36],"mirror":"x","piece":"head-bezel","other":"head-tub"}],"title":"Egg bot"}]},{"id":"tower","title":"Tall tower","about":"A tall narrow body with the face near the top, like a lighthouse. The empty lower part is room for what you add.","bodies":[{"id":"head","at":[0,0,0],"wall":2,"shapes":[{"rrect":"y","w":68,"h":120,"r":16,"span":[0,31.6],"at":[0,60],"name":"Tall tower shell"},{"hole":true,"box":[-38,-26,13,26,86.45,87.95],"copies":[[0,0,0],[0,0,2.8],[0,0,5.6],[0,0,8.4]]},{"hole":true,"tear":"z","r":5,"span":[-0.1,2.1],"at":[0,18],"tip":"-y"}],"seams":[{"axis":"y","at":4,"band":1.6}],"pieces":[{"id":"head-bezel","title":"Face bezel","material":"PETG","colour":"green","print":"y_front_down"},{"id":"head-seam","title":"Head light seam","material":"PETG clear","colour":"glow","print":"y_front_down"},{"id":"head-tub","title":"Head shell","material":"PETG","colour":"graphite","print":"y_back_down"}],"parts":[{"recipe":"lcd-2in","name":"screen","at":[0,3.5,78]},{"recipe":"cam-board","name":"brain","at":[0,25.6,78],"turn":[[0,0,180]]},{"recipe":"camera-ov5640","name":"camera","at":[0,3.6,103.95]},{"recipe":"speaker-1217","name":"speaker","at":[31,20.5,90.95],"turn":[[0,0,90]]},{"recipe":"snap-hook","name":"hook-r0","at":[32,4,73],"piece":"head-bezel","other":"head-tub"},{"recipe":"snap-hook","name":"hook-l0","at":[-32,4,73],"mirror":"x","piece":"head-bezel","other":"head-tub"},{"recipe":"snap-hook","name":"hook-r1","at":[32,4,83],"piece":"head-bezel","other":"head-tub"},{"recipe":"snap-hook","name":"hook-l1","at":[-32,4,83],"mirror":"x","piece":"head-bezel","other":"head-tub"}],"title":"Tall tower"}]},{"id":"crawler","title":"Wide crawler","about":"A long, low chassis on two wheels set far apart, so it is hard to tip, with a wide head on top.","bodies":[{"id":"head","at":[0,-14,30.6],"wall":2,"shapes":[{"rrect":"y","w":84,"h":60,"r":10,"span":[0,31.6],"at":[0,30],"name":"Crawler head shell"},{"hole":true,"box":[-46,-34,13,26,32.5,34],"copies":[[0,0,0],[0,0,2.8],[0,0,5.6],[0,0,8.4]]},{"hole":true,"tear":"z","r":5,"span":[-0.1,2.1],"at":[0,18],"tip":"-y"}],"seams":[{"axis":"y","at":4,"band":1.6}],"pieces":[{"id":"head-bezel","title":"Face bezel","material":"PETG","colour":"yellow","print":"y_front_down"},{"id":"head-seam","title":"Head light seam","material":"PETG clear","colour":"glow","print":"y_front_down"},{"id":"head-tub","title":"Head shell","material":"PETG","colour":"graphite","print":"y_back_down"}],"parts":[{"recipe":"lcd-2in","name":"screen","at":[0,3.5,24.05]},{"recipe":"cam-board","name":"brain","at":[0,25.6,24.05],"turn":[[0,0,180]]},{"recipe":"camera-ov5640","name":"camera","at":[0,3.6,50]},{"recipe":"speaker-1217","name":"speaker","at":[39,20.5,37],"turn":[[0,0,90]]},{"recipe":"snap-hook","name":"hook-r0","at":[40,4,18],"piece":"head-bezel","other":"head-tub"},{"recipe":"snap-hook","name":"hook-l0","at":[-40,4,18],"mirror":"x","piece":"head-bezel","other":"head-tub"},{"recipe":"snap-hook","name":"hook-r1","at":[40,4,28],"piece":"head-bezel","other":"head-tub"},{"recipe":"snap-hook","name":"hook-l1","at":[-40,4,28],"mirror":"x","piece":"head-bezel","other":"head-tub"},{"recipe":"m3-insert","name":"insert-r","at":[27,22,0],"turn":[[90,0,0]],"piece":"head-tub"},{"recipe":"m3-insert","name":"insert-l","at":[-27,22,0],"turn":[[90,0,0]],"mirror":"x","piece":"head-tub"}],"title":"Crawler head"},{"id":"base","at":[0,0,0],"wall":2,"shapes":[{"rrect":"z","w":124,"h":72,"r":20,"span":[0,30.6],"at":[0,0]},{"fill":true,"rrect":"z","w":124,"h":72,"r":20,"span":[27.6,30.6],"at":[0,0]},{"hole":true,"cyl":"z","r":6,"span":[27.5,31],"at":[0,4]}],"seams":[{"axis":"z","at":26,"band":1.6}],"pieces":[{"id":"base-chassis","title":"Base chassis","material":"PETG","colour":"blue","print":"flat"},{"id":"base-seam","title":"Base light seam","material":"PETG clear","colour":"glow","print":"flat"},{"id":"base-lid","title":"Base lid","material":"PETG","colour":"bone","print":"flip"}],"parts":[{"recipe":"fs90r-wheel","name":"right","at":[46,0,10],"turn":[[0,0,90]]},{"recipe":"fs90r-wheel","name":"left","at":[-46,0,10],"turn":[[0,0,-90]]},{"recipe":"glide","name":"front","at":[0,-28,0],"turn":[[90,0,0]]},{"recipe":"glide","name":"back","at":[0,28,0],"turn":[[90,0,0]]},{"recipe":"m3-screw","name":"head-screw-r","at":[27,8,27.6],"turn":[[90,0,0]],"piece":"base-lid"},{"recipe":"m3-screw","name":"head-screw-l","at":[-27,8,27.6],"turn":[[90,0,0]],"piece":"base-lid"},{"recipe":"m3-column","name":"column-rb","at":[27,23,0],"turn":[[90,0,0]],"piece":"base-chassis","other":"base-lid"},{"recipe":"m3-column","name":"column-rf","at":[27,-23,0],"turn":[[90,0,0]],"piece":"base-chassis","other":"base-lid"},{"recipe":"m3-column","name":"column-lb","at":[-27,23,0],"turn":[[90,0,0]],"piece":"base-chassis","other":"base-lid"},{"recipe":"m3-column","name":"column-lf","at":[-27,-23,0],"turn":[[90,0,0]],"piece":"base-chassis","other":"base-lid"}],"title":"Crawler base"}]},{"id":"round-head","title":"Round head on a stand","about":"A rounded head on a tall round stand. Two screws hold it on; the stand is empty inside for batteries and wires.","bodies":[{"id":"head","at":[0,-14,44],"wall":2,"shapes":[{"rrect":"y","w":76,"h":70,"r":14,"span":[0,31.6],"at":[0,35],"name":"Round head shell"},{"hole":true,"box":[-42,-30,13,26,35.45,36.95],"copies":[[0,0,0],[0,0,2.8],[0,0,5.6],[0,0,8.4]]},{"hole":true,"tear":"z","r":5,"span":[-0.1,2.1],"at":[0,18],"tip":"-y"}],"seams":[{"axis":"y","at":4,"band":1.6}],"pieces":[{"id":"head-bezel","title":"Face bezel","material":"PETG","colour":"magenta","print":"y_front_down"},{"id":"head-seam","title":"Head light seam","material":"PETG clear","colour":"glow","print":"y_front_down"},{"id":"head-tub","title":"Head shell","material":"PETG","colour":"white","print":"y_back_down"}],"parts":[{"recipe":"lcd-2in","name":"screen","at":[0,3.5,27]},{"recipe":"cam-board","name":"brain","at":[0,25.6,27],"turn":[[0,0,180]]},{"recipe":"camera-ov5640","name":"camera","at":[0,3.6,52.95]},{"recipe":"speaker-1217","name":"speaker","at":[35,20.5,39.95],"turn":[[0,0,90]]},{"recipe":"snap-hook","name":"hook-r0","at":[36,4,22],"piece":"head-bezel","other":"head-tub"},{"recipe":"snap-hook","name":"hook-l0","at":[-36,4,22],"mirror":"x","piece":"head-bezel","other":"head-tub"},{"recipe":"snap-hook","name":"hook-r1","at":[36,4,32],"piece":"head-bezel","other":"head-tub"},{"recipe":"snap-hook","name":"hook-l1","at":[-36,4,32],"mirror":"x","piece":"head-bezel","other":"head-tub"},{"recipe":"m3-insert","name":"insert-r","at":[22,22,0],"turn":[[90,0,0]],"piece":"head-tub"},{"recipe":"m3-insert","name":"insert-l","at":[-22,22,0],"turn":[[90,0,0]],"mirror":"x","piece":"head-tub"}],"title":"Round head"},{"id":"base","at":[0,0,0],"wall":2,"shapes":[{"rrect":"z","w":64,"h":64,"r":32,"span":[0,44],"at":[0,0]},{"fill":true,"rrect":"z","w":64,"h":64,"r":32,"span":[41,44],"at":[0,0]},{"hole":true,"cyl":"z","r":6,"span":[40.9,44.4],"at":[0,4]}],"seams":[{"axis":"z","at":38,"band":1.6}],"pieces":[{"id":"base-chassis","title":"Base chassis","material":"PETG","colour":"graphite","print":"flat"},{"id":"base-seam","title":"Base light seam","material":"PETG clear","colour":"glow","print":"flat"},{"id":"base-lid","title":"Base lid","material":"PETG","colour":"bone","print":"flip"}],"parts":[{"recipe":"m3-column-tall","name":"column-rb","at":[18,20,0],"turn":[[90,0,0]],"piece":"base-chassis","other":"base-lid"},{"recipe":"m3-column-tall","name":"column-rf","at":[18,-20,0],"turn":[[90,0,0]],"piece":"base-chassis","other":"base-lid"},{"recipe":"m3-column-tall","name":"column-lb","at":[-18,20,0],"turn":[[90,0,0]],"piece":"base-chassis","other":"base-lid"},{"recipe":"m3-column-tall","name":"column-lf","at":[-18,-20,0],"turn":[[90,0,0]],"piece":"base-chassis","other":"base-lid"},{"recipe":"m3-screw","name":"head-screw-r","at":[22,8,41],"turn":[[90,0,0]],"piece":"base-lid"},{"recipe":"m3-screw","name":"head-screw-l","at":[-22,8,41],"turn":[[90,0,0]],"piece":"base-lid"}],"title":"Stand"}]}],"refs":[{"id":"mini2","title":"Mini","about":"The Mini v2: two 64 mm wheels outside the body, two 18650 cells flat on the floor between them, one tail glide, and a wide shield face that tapers to a narrow chin. Same frames as the old Mini: X right, Y back (the face looks toward -Y), Z up.","bodies":[{"id":"head","title":"Head","at":[0,-10,45.1],"wall":2,"shapes":[{"prism":"y","pts":[[-16,0],[16,0],[37.969,19.103],[38.199,19.326],[38.404,19.572],[38.582,19.839],[38.73,20.123],[38.847,20.421],[38.932,20.73],[38.983,21.047],[39,21.367],[39,45.95],[38.813,47.981],[38.257,49.943],[37.353,51.77],[36.129,53.402],[34.627,54.782],[32.899,55.864],[31.002,56.612],[29,57],[22.677,57.632],[21.861,57.771],[21.072,58.021],[20.325,58.377],[19.635,58.832],[19.013,59.378],[18.472,60.004],[18.023,60.699],[17.674,61.449],[15.233,67.795],[14.911,68.474],[14.491,69.097],[13.982,69.651],[13.397,70.122],[12.747,70.499],[12.048,70.775],[11.315,70.944],[10.566,71],[-10.566,71],[-11.315,70.944],[-12.048,70.775],[-12.747,70.499],[-13.397,70.122],[-13.982,69.651],[-14.491,69.097],[-14.911,68.474],[-15.233,67.795],[-17.674,61.449],[-18.023,60.699],[-18.472,60.004],[-19.013,59.378],[-19.635,58.832],[-20.325,58.377],[-21.072,58.021],[-21.861,57.771],[-22.677,57.632],[-29,57],[-31.002,56.612],[-32.899,55.864],[-34.627,54.782],[-36.129,53.402],[-37.353,51.77],[-38.257,49.943],[-38.813,47.981],[-39,45.95],[-39,21.367],[-38.983,21.047],[-38.932,20.73],[-38.847,20.421],[-38.73,20.123],[-38.582,19.839],[-38.404,19.572],[-38.199,19.326],[-37.969,19.103]],"span":[0,31.6]},{"hole":true,"box":[-39.5,-36.5,13,26,30,31.5],"copies":[[0,0,0],[0,0,2.8],[0,0,5.6],[0,0,8.4]]},{"hole":true,"tear":"z","r":5,"span":[-0.1,2.1],"at":[0,18],"tip":"-y"}],"seams":[{"axis":"y","at":4,"band":1.6}],"pieces":[{"id":"head-bezel","title":"Face bezel","material":"PETG","colour":"teal","print":"y_front_down"},{"id":"head-seam","title":"Head light seam","material":"PETG clear","colour":"glow","print":"y_front_down"},{"id":"head-tub","title":"Head shell","material":"PETG","colour":"bone","print":"y_back_down"}],"parts":[{"recipe":"lcd-2in","name":"screen","at":[0,3.5,36]},{"recipe":"cam-board","name":"brain","at":[0,25.6,36],"turn":[[0,0,180]]},{"recipe":"camera-ov5640","name":"camera","at":[0,3.6,62]},{"recipe":"speaker-1217","name":"speaker","at":[36,20.5,34],"turn":[[0,0,90]]},{"recipe":"snap-hook","name":"hook-r26","at":[37,4,26],"piece":"head-bezel","other":"head-tub"},{"recipe":"snap-hook","name":"hook-l26","at":[-37,4,26],"mirror":"x","piece":"head-bezel","other":"head-tub"},{"recipe":"snap-hook","name":"hook-r40","at":[37,4,40],"piece":"head-bezel","other":"head-tub"},{"recipe":"snap-hook","name":"hook-l40","at":[-37,4,40],"mirror":"x","piece":"head-bezel","other":"head-tub"},{"recipe":"m3-insert","name":"insert-r","at":[10,22,0],"turn":[[90,0,0]],"piece":"head-tub"},{"recipe":"m3-insert","name":"insert-l","at":[-10,22,0],"turn":[[90,0,0]],"mirror":"x","piece":"head-tub"}]},{"id":"belly","title":"Belly","at":[0,0,0],"wall":2,"shapes":[{"prism":"x","pts":[[-12.5,3.1],[81.6,3.1],[81.6,41.1],[77.6,45.1],[-16,45.1],[-22,39.1],[-22,12.6]],"span":[-36,36]},{"fill":true,"box":[-34.5,34.5,-14.5,80.1,42.1,45.1]},{"hole":true,"cyl":"z","r":6,"span":[42,45.6],"at":[0,8]}],"seams":[{"axis":"z","at":40.5,"band":1.6}],"pieces":[{"id":"belly-chassis","title":"Belly chassis","material":"PETG clear","colour":"smoke","print":"flat"},{"id":"belly-seam","title":"Belly light seam","material":"PETG clear","colour":"glow","print":"flat"},{"id":"belly-lid","title":"Belly lid","material":"PETG","colour":"graphite","print":"flip"}],"parts":[{"recipe":"fs90r-wheel-64","name":"right","at":[34.2,0,32],"turn":[[0,0,90]],"piece":"belly-chassis"},{"recipe":"fs90r-wheel-64","name":"left","at":[-34.2,0,32],"turn":[[0,0,-90]],"mirror":"x","piece":"belly-chassis"},{"recipe":"battery-2x18650","name":"battery","at":[0,27.6,5.1],"piece":"belly-chassis"},{"recipe":"charger-usbc-4410","name":"charger","at":[31,67.19999999999999,28],"turn":[[0,0,90]],"piece":"belly-chassis"},{"recipe":"boost-5v-2a","name":"boost","at":[-19,78.19999999999999,28],"turn":[[0,0,180]],"piece":"belly-chassis"},{"recipe":"glide-tail","name":"tail","at":[0,73.5,3.1],"turn":[[90,0,0]]},{"recipe":"m3-screw","name":"head-screw-r","at":[10,12,42.1],"turn":[[90,0,0]],"piece":"belly-lid"},{"recipe":"m3-screw","name":"head-screw-l","at":[-10,12,42.1],"turn":[[90,0,0]],"piece":"belly-lid"},{"recipe":"m3-column-tall","name":"column-1","at":[28.5,36,3.1],"turn":[[90,0,0]],"piece":"belly-chassis","other":"belly-lid"},{"recipe":"m3-column-tall","name":"column-2","at":[-28.5,36,3.1],"turn":[[90,0,0]],"piece":"belly-chassis","other":"belly-lid"},{"recipe":"m3-column-tall","name":"column-3","at":[-28.5,66,3.1],"turn":[[90,0,0]],"piece":"belly-chassis","other":"belly-lid"}]}]},{"id":"mini","title":"Mini","about":"The Mini rebuilt from shapes + recipes (BAB-0044 step 2). Same frames as parts/bots/mini.py: X right, Y back (the face looks toward -Y), Z up; the head sits on the base lid.","bodies":[{"id":"head","at":[0,-14,30.6],"wall":2,"shapes":[{"rrect":"y","w":68,"h":60,"r":10,"span":[0,31.6],"at":[0,30]},{"hole":true,"box":[-34.5,-31.5,13,26,32.5,34],"copies":[[0,0,0],[0,0,2.8],[0,0,5.6],[0,0,8.4]]},{"hole":true,"tear":"z","r":5,"span":[-0.1,2.1],"at":[0,18],"tip":"-y"}],"seams":[{"axis":"y","at":4,"band":1.6}],"pieces":[{"id":"head-bezel","title":"Face bezel","material":"PETG","colour":"bone","print":"y_front_down"},{"id":"head-seam","title":"Head light seam","material":"PETG clear","colour":"glow","print":"y_front_down"},{"id":"head-tub","title":"Head shell","material":"PETG","colour":"graphite","print":"y_back_down"}],"parts":[{"recipe":"lcd-2in","name":"screen","at":[0,3.5,24.05]},{"recipe":"cam-board","name":"brain","at":[0,25.6,24.05],"turn":[[0,0,180]]},{"recipe":"camera-ov5640","name":"camera","at":[0,3.6,50]},{"recipe":"speaker-1217","name":"speaker","at":[31,20.5,37],"turn":[[0,0,90]]},{"recipe":"snap-hook","name":"hook-r18","at":[32,4,18],"piece":"head-bezel","other":"head-tub"},{"recipe":"snap-hook","name":"hook-r28","at":[32,4,28],"piece":"head-bezel","other":"head-tub"},{"recipe":"snap-hook","name":"hook-l18","at":[-32,4,18],"mirror":"x","piece":"head-bezel","other":"head-tub"},{"recipe":"snap-hook","name":"hook-l28","at":[-32,4,28],"mirror":"x","piece":"head-bezel","other":"head-tub"},{"recipe":"m3-insert","name":"insert-r","at":[27,22,0],"turn":[[90,0,0]],"piece":"head-tub"},{"recipe":"m3-insert","name":"insert-l","at":[-27,22,0],"turn":[[90,0,0]],"mirror":"x","piece":"head-tub"}]},{"id":"base","at":[0,0,0],"wall":2,"shapes":[{"rrect":"z","w":80,"h":72,"r":20,"span":[0,30.6],"at":[0,0]},{"fill":true,"rrect":"z","w":80,"h":72,"r":20,"span":[27.6,30.6],"at":[0,0]},{"hole":true,"cyl":"z","r":6,"span":[27.5,31],"at":[0,4]}],"seams":[{"axis":"z","at":26,"band":1.6}],"pieces":[{"id":"base-chassis","title":"Base chassis","material":"PETG","colour":"graphite","print":"flat"},{"id":"base-seam","title":"Base light seam","material":"PETG clear","colour":"glow","print":"flat"},{"id":"base-lid","title":"Base lid","material":"PETG","colour":"bone","print":"flip"}],"parts":[{"recipe":"fs90r-wheel","name":"right","at":[24,0,10],"turn":[[0,0,90]]},{"recipe":"fs90r-wheel","name":"left","at":[-24,0,10],"turn":[[0,0,-90]]},{"recipe":"glide","name":"front","at":[0,-28,0],"turn":[[90,0,0]]},{"recipe":"glide","name":"back","at":[0,28,0],"turn":[[90,0,0]]},{"recipe":"m3-screw","name":"head-screw-r","at":[27,8,27.6],"turn":[[90,0,0]],"piece":"base-lid"},{"recipe":"m3-screw","name":"head-screw-l","at":[-27,8,27.6],"turn":[[90,0,0]],"piece":"base-lid"},{"recipe":"m3-column","name":"column-rb","at":[27,23,0],"turn":[[90,0,0]],"piece":"base-chassis","other":"base-lid"},{"recipe":"m3-column","name":"column-rf","at":[27,-23,0],"turn":[[90,0,0]],"piece":"base-chassis","other":"base-lid"},{"recipe":"m3-column","name":"column-lb","at":[-27,23,0],"turn":[[90,0,0]],"piece":"base-chassis","other":"base-lid"},{"recipe":"m3-column","name":"column-lf","at":[-27,-23,0],"turn":[[90,0,0]],"piece":"base-chassis","other":"base-lid"}]}]},{"id":"desk","title":"Desk companion","about":"The Mini's head on a neck that turns and nods. The base holds the turning servo and the servo driver board; the neck holds the nodding servo on its side; the head's cheek takes its horn. Moves are eased: a jump across the whole range would rock the base.","bodies":[{"id":"base","at":[0,0,0],"wall":2,"shapes":[{"rrect":"z","w":96,"h":88,"r":32,"span":[0,44],"at":[0,0]},{"fill":true,"rrect":"z","w":96,"h":88,"r":32,"span":[41,44],"at":[0,0]},{"hole":true,"cyl":"z","r":5,"span":[40.9,44.1],"at":[-17,0]}],"seams":[{"axis":"z","at":38,"band":1.6}],"pieces":[{"id":"base-chassis","title":"Base chassis","material":"PETG","colour":"graphite","print":"flat"},{"id":"base-seam","title":"Base light seam","material":"PETG clear","colour":"glow","print":"flat"},{"id":"base-lid","title":"Base lid","material":"PETG","colour":"bone","print":"flip"}],"parts":[{"recipe":"scs0009-joint-posts","name":"pan","at":[0,0,44],"turn":[[-90,0,0]],"moving":"neck","range":[-120,120]},{"recipe":"bus-servo-adapter","name":"servo-driver","at":[0,40,21],"turn":[[0,0,180]]},{"recipe":"m3-column-tall","name":"column-rb","at":[30,26,0],"turn":[[90,0,0]],"piece":"base-chassis","other":"base-lid"},{"recipe":"m3-column-tall","name":"column-rf","at":[30,-26,0],"turn":[[90,0,0]],"piece":"base-chassis","other":"base-lid"},{"recipe":"m3-column-tall","name":"column-lb","at":[-30,26,0],"turn":[[90,0,0]],"piece":"base-chassis","other":"base-lid"},{"recipe":"m3-column-tall","name":"column-lf","at":[-30,-26,0],"turn":[[90,0,0]],"piece":"base-chassis","other":"base-lid"}]},{"id":"neck","at":[0,0,0],"wall":2,"shapes":[{"rrect":"x","w":36,"h":20,"r":6,"span":[-22,22],"at":[0,57]},{"box":[-22,22,-18,18,57,78]},{"cyl":"x","r":18,"span":[-22,22],"at":[0,78]},{"hole":true,"box":[-20,-15,-4.5,4.5,46.9,49.1]},{"hole":true,"box":[-20,-15,-4,4,92,96.5]}],"seams":[{"axis":"x","at":0,"band":1.6}],"pieces":[{"id":"neck-left","title":"Neck left","material":"PETG","colour":"graphite","print":"x_min_down"},{"id":"neck-seam","title":"Neck light seam","material":"PETG clear","colour":"glow","print":"x_min_down"},{"id":"neck-right","title":"Neck right","material":"PETG","colour":"graphite","print":"x_max_down"}],"parts":[{"recipe":"scs0009-joint-posts","name":"tilt","at":[22,0,78],"turn":[[0,0,90],[-90,0,0]],"piece":"neck-left","moving":"head","movingPiece":"head-tub","range":[-30,30]},{"recipe":"snap-hook","name":"neck-hook-f58","at":[0,-16,58],"turn":[[0,0,-90]],"piece":"neck-left","other":"neck-right"},{"recipe":"snap-hook","name":"neck-hook-b58","at":[0,16,58],"turn":[[0,0,-90]],"mirror":"x","piece":"neck-left","other":"neck-right"},{"recipe":"snap-hook","name":"neck-hook-f76","at":[0,-16,76],"turn":[[0,0,-90]],"piece":"neck-left","other":"neck-right"},{"recipe":"snap-hook","name":"neck-hook-b76","at":[0,16,76],"turn":[[0,0,-90]],"mirror":"x","piece":"neck-left","other":"neck-right"}]},{"id":"head","at":[0,-22,99],"wall":2,"shapes":[{"rrect":"y","w":68,"h":60,"r":10,"span":[0,40],"at":[0,30]},{"hole":true,"box":[-34.5,-31.5,13,26,32.5,34],"copies":[[0,0,0],[0,0,2.8],[0,0,5.6],[0,0,8.4]]},{"hole":true,"tear":"z","r":5,"span":[-0.1,2.1],"at":[-17.5,22],"tip":"-y"},{"fill":true,"rrect":"y","w":6,"h":37,"r":2.5,"span":[8,40],"at":[28,-16.5]},{"fill":true,"rrect":"y","w":6,"h":37,"r":2.5,"span":[8,40],"at":[-28,-16.5]}],"seams":[{"axis":"y","at":4,"band":1.6}],"pieces":[{"id":"head-bezel","title":"Face bezel","material":"PETG","colour":"bone","print":"y_front_down"},{"id":"head-seam","title":"Head light seam","material":"PETG clear","colour":"glow","print":"y_front_down"},{"id":"head-tub","title":"Head shell","material":"PETG","colour":"graphite","print":"y_back_down"}],"parts":[{"recipe":"lcd-2in","name":"screen","at":[0,3.5,24.05]},{"recipe":"cam-board","name":"brain","at":[0,34,24.05],"turn":[[0,0,180]]},{"recipe":"camera-ov5640","name":"camera","at":[0,3.6,50]},{"recipe":"speaker-1217","name":"speaker","at":[31,24,37],"turn":[[0,0,90]]},{"recipe":"snap-hook","name":"hook-r18","at":[32,4,18],"piece":"head-bezel","other":"head-tub"},{"recipe":"snap-hook","name":"hook-r28","at":[32,4,28],"piece":"head-bezel","other":"head-tub"},{"recipe":"snap-hook","name":"hook-l18","at":[-32,4,18],"mirror":"x","piece":"head-bezel","other":"head-tub"},{"recipe":"snap-hook","name":"hook-l28","at":[-32,4,28],"mirror":"x","piece":"head-bezel","other":"head-tub"}]}]},{"id":"arm-test","title":"Arm test","about":"A test design for joints (not a product): a base on four glides with an SCS0009 lying on its side, spline out of the right wall, turning a solid arm about X. Used by shared/gen/check-rules.mjs.","bodies":[{"id":"base","at":[0,0,0],"wall":2,"shapes":[{"rrect":"z","w":80,"h":60,"r":14,"span":[0,44],"at":[0,0]}],"seams":[{"axis":"z","at":38}],"pieces":[{"id":"base-shell","title":"Base shell","material":"PETG","colour":"graphite","print":"flat"},{"id":"base-lid","title":"Base lid","material":"PETG","colour":"bone","print":"flip"}],"parts":[{"recipe":"cam-board","name":"brain","at":[-12,24,22],"turn":[[0,0,180]]},{"recipe":"scs0009-joint","name":"shoulder","at":[40,0,10],"turn":[[0,0,90]],"moving":"arm"},{"recipe":"glide","name":"glide-fl","at":[-28,-20,0],"turn":[[90,0,0]]},{"recipe":"glide","name":"glide-fr","at":[28,-20,0],"turn":[[90,0,0]]},{"recipe":"glide","name":"glide-bl","at":[-28,20,0],"turn":[[90,0,0]]},{"recipe":"glide","name":"glide-br","at":[28,20,0],"turn":[[90,0,0]]}]},{"id":"arm","at":[0,0,0],"wall":2,"shapes":[{"fill":true,"rrect":"x","w":28,"h":70,"r":14,"span":[43,55],"at":[0,31]}],"pieces":[{"id":"arm","title":"Arm","material":"PETG","colour":"bone","print":"auto"}]}]}],"prices":{"_about":"BAB-0063. What the bought parts cost, one entry per recipe id (shared/recipes/*.json). Every number here is read from a research note, never guessed: a part with no sourced price has price: null and the editor says 'price to find'. A recipe with no entry at all also says 'price to find'. CAD, before tax (New Brunswick HST is 15%, added at checkout). Fields of an item: what (the thing to buy), pack_price (CAD for one pack), pack_size (how many units one pack holds), uses (units one placed part uses; default 1), per_design (true = one pack serves the whole design, however many are placed: a roll of tape), source (a link, or a note naming the page it was read on), seen (the date the price was read), research (the note and section). Build it yourself = whole packs. Built by 3D3D = the units used at cost, plus markup_pct (a pack is bought once; the leftovers stay in 3D3D's stock).","currency":"CAD","rules":{"markup_pct":15,"markup_source":"The team lead, 2026-11-03: 'if we build it for the person, then we charge 15% on the parts and pieces' (docs/work-orders/BAB-0063-editor-round-two.md).","print":{"rate_per_g":{"PETG":0.11,"TPU 95A":0.18,"ASA":0.13},"variants":"A material whose name starts with a rated material's name is charged at that rate: PETG clear, PETG clear smoked and PETG + PTFE tape (the glide's printed part; the tape is a bought line) are PETG.","setup":5,"bed":[{"up_to_h":6,"fee":10},{"up_to_h":24,"fee":14},{"fee":18}],"min_per_g":3.5,"minimum":18,"source":"The 3d3d.ca print calculator, the team lead's rule as written in docs/work-orders/BAB-0063-editor-round-two.md: PETG $0.11/g, TPU 95A $0.18/g, ASA $0.13/g; $5 setup once per job; bed rental once per plate ($10 up to 6 h, $14 for 6 to 24 h, $18 over 24 h), hours estimated at 3.5 min/g; $18 minimum. CAD, before HST. PETG clear is PETG."},"build_fee":{"amount":100,"build":50,"test":50,"label":"Build $50 + test $50: it arrives working","source":"The team lead, 2026-11-04, in chat: 'Build and test is $50 for the build, $50 for the testing. Then that's sending you a robot that's ready to function 100%.' (docs/work-orders/BAB-0071-customer-path-and-order.md)","note":"A flat fee per built bot, part of the Built by 3D3D total. CAD, before tax."},"finishing":{"standard_per_h":25,"advanced_per_h":35,"label":"Finishing","source":"3d3d.ca's own post-processing rates: ~/3d3d-site-makers/app/lib/pricing.ts POST_PROCESSING_RATES (standard $25.00/h, advanced $35.00/h, charged by the minute). The team lead, 2026-11-04: post-processing such as complex support removal on many pieces is a charge.","note":"$0 when every printed piece passes the print gate (so no supports) and no piece is a pinned kit piece. Otherwise charged at the standard rate by the minutes 3D3D spends when it slices and finishes the job; no minutes are guessed here, so that part is not in the total until then."},"shipping":"collected up front, at checkout"},"parts":{"lcd-2in":{"items":[{"what":"Waveshare 2\" capacitive touch LCD (18-pin FPC option)","pack_price":29.99,"pack_size":1,"uses":1,"source":"https://www.amazon.ca/dp/B0DMRMWD3Q","seen":"2026-11-02","research":"R8b section 6 (Amazon / waveshare, Fri Nov 6, 4.2 stars from 11 ratings)"}]},"cam-board":{"items":[{"what":"Waveshare ESP32-S3-CAM-OV5640 board (camera and 2 W speaker in the box)","pack_price":37.99,"pack_size":1,"uses":1,"source":"https://www.amazon.ca/dp/B0GS1HT4LH","seen":"2026-11-02","research":"R8b section 1 (Amazon / waveshare, Fri Nov 6, 3.8 stars from 9 ratings)"}]},"camera-ov5640":{"included_in":"cam-board","research":"R8b section 6: the box holds the baseboard, the camera and a 1217 speaker"},"speaker-1217":{"included_in":"cam-board","research":"R8b section 6 and R4: the Waveshare camera board ships with its 1217 8 ohm 2 W speaker"},"fs90r-wheel":{"items":[{"what":"FS90R continuous servo, 2-pack with wheels (DIYmalls)","pack_price":19.97,"pack_size":2,"uses":1,"source":"https://www.amazon.ca/dp/B086ZGTLZB","seen":"2026-11-02","research":"R8b section 1 (Amazon / DIYmalls, Wed Nov 4, 4.4 stars from 70 ratings)"}]},"glide":{"items":[{"what":"PTFE glass-cloth tape 10 mm x 10 m (the pad on the glide's dome), sold by the roll","pack_price":9.98,"pack_size":1,"per_design":true,"source":"https://www.amazon.ca/dp/B09TQG5D8G","seen":"2026-11-02","research":"R8b section 1 (skycabin, Amazon / sky_1965, 4.5 stars from 22 ratings); R8 section 1d: one roll makes many corner pads"},{"what":"M3 x 4 self-tapping screw","pack_price":null,"hint":"R2 section 6 lists mixed self-tapping kits at $16.99 to $18.99, but no page showed that an M3 x 4 is in one.","research":"R2 section 6"}]},"m3-insert":{"items":[{"what":"M3 brass heat-set inserts, 120 pieces","pack_price":9.49,"pack_size":120,"uses":1,"source":"https://www.amazon.ca/dp/B0GTLGGYY7","seen":"2026-11-02","research":"R2 section 6 and R8b section 1 (Amazon, 5.0 stars from 3 ratings; check the thread is right-hand)"}]},"m3-screw":{"items":[{"what":"M3 x 8 pan-head screw","pack_price":null,"hint":"R2 section 6 lists mixed M2/M3/M4 screw kits at $16.99 to $18.99, but no page showed that an M3 x 8 is in one.","research":"R2 section 6"}]},"m3-column":{"items":[{"what":"M3 x 30 screw","pack_price":null,"hint":"No M3 x 30 listing was read in R2 or R8.","research":"R2 section 6"}]},"m3-column-tall":{"items":[{"what":"M3 x 40 screw","pack_price":null,"hint":"No M3 x 40 listing was read in R2 or R8.","research":"R2 section 6"}]},"snap-hook":{"none":"Printed in the two pieces it joins: nothing to buy.","research":"shared/recipes/snap-hook.json"},"bus-servo-adapter":{"items":[{"what":"Waveshare Bus Servo Adapter (A)","pack_price":16.99,"pack_size":1,"uses":1,"source":"https://www.amazon.ca/dp/B0CJ6TP3TP","seen":"2026-11-02","research":"R8b section 1 (Amazon / waveshare, Wed Nov 4, 4.4 stars from 42 ratings)"}]},"scs0009-joint":{"items":[{"what":"Feetech SCS0009 bus servo, 2-pack","pack_price":35.99,"pack_size":2,"uses":1,"source":"https://www.amazon.ca/dp/B0HBWP4574","seen":"2026-11-02","research":"R8 section 1a and R8b section 1 (the price was read on the search page; that listing was not opened)"}]},"scs0009-joint-posts":{"items":[{"what":"Feetech SCS0009 bus servo, 2-pack","pack_price":35.99,"pack_size":2,"uses":1,"source":"https://www.amazon.ca/dp/B0HBWP4574","seen":"2026-11-02","research":"R8 section 1a and R8b section 1 (the price was read on the search page; that listing was not opened)"}]},"max98357a":{"items":[{"what":"MAX98357A I2S amp board, 2-pack (a generic board of the same chip; the recipe names Adafruit 3006, whose price was not read)","pack_price":10.89,"pack_size":2,"uses":1,"source":"https://www.amazon.ca/dp/B0B2NSMV55","seen":"2026-11-02","research":"R8b section 4 (DAOKAI, Amazon / DAOKAI CA, Thu Nov 5, 4.1 stars from 54 ratings)"}]},"pca9685":{"items":[{"what":"PCA9685 16-channel PWM servo driver (a generic board of the same chip; the recipe names Adafruit 815, whose price was not read)","pack_price":14.2,"pack_size":1,"uses":1,"source":"https://www.amazon.ca/dp/B07RMTN4NZ","seen":"2026-11-02","research":"R2 section 4 (Dorhea, amazon.ca)"}]},"speaker-40mm":{"items":[{"what":"Adafruit 40 mm speaker, product 3968","pack_price":null,"hint":"Its amazon.ca price was not read in R3 or R8.","research":"R3"}]},"fs90r-wheel-64":{"items":[{"what":"FS90R continuous servo, 2-pack (the 64 mm wheel and tyre are printed; the pack's own horn screws on)","pack_price":19.97,"pack_size":2,"uses":1,"source":"https://www.amazon.ca/dp/B086ZGTLZB","seen":"2026-11-02","research":"R8b section 1 (Amazon / DIYmalls, Wed Nov 4, 4.4 stars from 70 ratings)"}]},"battery-2x18650":{"items":[{"what":"2 x 18650 battery holder with leads (uxcell), 2-pack","pack_price":9.39,"pack_size":2,"uses":1,"source":"https://www.amazon.ca/dp/B092PMWQ4W","seen":"2026-11-02","research":"R2 lines 361 and R8 line 59 (2-pack $9.39)"},{"what":"18650 cells, two (e.g. Panasonic NCR18650B, from a shop that sells genuine cells)","pack_price":null,"pack_size":2,"uses":2,"hint":"no 18650 cell listing was priced in the research yet","research":"R2 line 360 (the cell's size and mass only)"}]},"charger-usbc-4410":{"items":[{"what":"Adafruit #4410 Micro Lipo USB-C charger","pack_price":null,"pack_size":1,"uses":1,"hint":"the research measured its size and holes (Adafruit CAD, MIT) but did not read a Canadian price","research":"R2 line 363"}]},"boost-5v-2a":{"items":[{"what":"5 V 2 A charge/boost boards, 5-pack (DAOKI)","pack_price":15.79,"pack_size":5,"uses":1,"source":"https://www.amazon.ca/s?k=5V+boost+converter (search page; the DAOKI row)","seen":"2026-11-02","research":"R8 line 61 (DAOKI 5-pack $15.79, 4.5 stars from 14 ratings)"}]},"glide-tail":{"items":[{"what":"PTFE glass-cloth tape 10 mm x 10 m (the pad on the glide's dome), sold by the roll","pack_price":9.98,"pack_size":1,"per_design":true,"source":"https://www.amazon.ca/dp/B09TQG5D8G","seen":"2026-11-02","research":"R8b section 1 (skycabin, Amazon / sky_1965, 4.5 stars from 22 ratings); R8 section 1d: one roll makes many corner pads"},{"what":"M3 x 4 self-tapping screw","pack_price":null,"hint":"R2 section 6 lists mixed self-tapping kits at $16.99 to $18.99, but no page showed that an M3 x 4 is in one.","research":"R2 section 6"}]}}}}
