"""Hobby servo with a single-arm horn. The case's underside is on the XY plane, centred on the origin, the case's long side along X, the output shaft up at the +X end. Fit dimensions come from each maker's drawing in the README; the shaft's place, the tabs' thickness, the holes and the horn are proportions, for looks.""" from steve import Model designation = "SG90" # Servo detail = "full" # full: with the horn, tab holes and output shaft; simple: case and tabs only # type: (case length, case width, length over the tabs, height to the tabs' top, height to the case's top, height overall) # SG90: Luxorparts item 87897 sheet, update Nov 30, 2017: 22.8, 12.4, 32.0, 15.6, 26.7, 15.6 + 15.8 (horn included). # S3003: Luxorparts item 87902 sheet, update Nov 30, 2017: 40.5, 20.2, 54.2, 29.5, 39.4, 29.5 + 19.0. # MG90S and MG996R: Tower Pro drawings, https://www.electronicoscaldas.com/datasheet/MG90S_Tower-Pro.pdf and MG996R_Tower-Pro.pdf: MG90S 22.5, 12, 32.5, 21, 35.5; MG996R 40.3, 20, 53.6, 26.6, 36.6, 47.6. # The MG90S drawing gives no case top: 0.75 of the way from the tabs to the top, for looks. SERVOS = { "SG90": (22.8, 12.4, 32.0, 15.6, 26.7, 31.4), "S3003": (40.5, 20.2, 54.2, 29.5, 39.4, 48.5), "MG90S": (22.5, 12.0, 32.5, 21.0, 31.9, 35.5), "MG996R": (40.3, 20.0, 53.6, 26.6, 36.6, 47.6), } length, width, span, tab_top, case_top, overall = SERVOS[designation] tab = 0.1 * width + 1 shaft_x = length / 2 - width / 2 model = Model() with model.sketch("case_sketch", on="XY", name="Case") as sk: sk.rect("case_rect", (-length / 2, -width / 2), (length / 2, width / 2)) model.extrude("case", "case_sketch", distance=case_top, name="Case") model.plane("tab_plane", on="XY", offset=tab_top - tab, name="Tabs") with model.sketch("tab_sketch", on="tab_plane", name="Tabs") as sk: sk.rect("tab_rect", (-span / 2, -width / 2), (span / 2, width / 2)) model.extrude("tabs", "tab_sketch", distance=tab, name="Tabs") if detail == "full": with model.sketch("holes_sketch", on="tab_plane", name="Tab holes") as sk: sk.circle("hole_left", (-(span + length) / 4, 0), 0.08 * width + 0.5) sk.circle("hole_right", ((span + length) / 4, 0), 0.08 * width + 0.5) model.extrude("holes", "holes_sketch", distance=tab, op="cut", name="Tab holes") horn = 0.14 * (overall - case_top) model.plane("boss_plane", on="XY", offset=case_top, name="Boss") with model.sketch("boss_sketch", on="boss_plane", name="Boss") as sk: sk.circle("boss_circle", (shaft_x, 0), 0.32 * width) model.extrude("boss", "boss_sketch", distance=0.35 * (overall - case_top), name="Boss") with model.sketch("shaft_sketch", on="boss_plane", name="Output shaft") as sk: sk.circle("shaft_circle", (shaft_x, 0), 0.17 * width) model.extrude("shaft", "shaft_sketch", distance=overall - case_top - horn, name="Output shaft") model.plane("horn_plane", on="XY", offset=overall - horn, name="Horn") with model.sketch("horn_sketch", on="horn_plane", name="Horn") as sk: sk.slot("horn_slot", (shaft_x, 0), (shaft_x - 1.2 * width, 0), 0.25 * width) model.extrude("horn", "horn_sketch", distance=horn, name="Horn") model.material("abs", color="#26282b") result = model.result()