11.5 - Implementation
Implementation
Fabrication
For our design fabrication process, we first created a detailed CAD model of our concept using SolidWorks. After finalizing the design, we manufactured the physical components through 3D printing. All parts of the robot were 3D printed, with the exception of the electronics, the stand, and the fasteners. The printed components were produced using a personal 3D printer owned by one of our teammates, which allowed us to quickly prototype, test, and make adjustments as needed. We used PLA filament for the leg assembly of our dog robot because it was accessible, easy to print with, and suitable for creating lightweight structural components. The screws and nuts used to assemble the robot were purchased separately and selected to securely connect the 3D-printed parts components.
Assembly
The robot leg assembly was constructed using a combination of 3D-printed PLA components, purchased hardware, servos, and a support stand to create a lightweight and functional mechanical system. The individual leg components were first modeled in SolidWorks and then fabricated using a teammate’s personal 3D printer. Once printed, the full leg was assembled by connecting the separate links and joints with purchased screws and nuts. These fasteners were used to secure the structure while still allowing the necessary rotational motion at the joints.
A key part of the assembly was integrating the servos with the leg mechanism and stand. To do this, we designed and 3D printed an additional connector piece that allowed the servos to mount securely to the stand. This helped keep the servos properly positioned during testing and provided stability while the leg was in motion. The knee mechanism was connected to the knee servo using a small rod, which transferred the servo’s rotation into movement at the knee joint. This linkage allowed the servo to drive the knee motion while keeping the overall assembly compact and supported.
A challenge during assembly was ensuring that the servo mounts, knee linkage, and leg joints were aligned correctly so the leg could move smoothly without binding. Small adjustments were needed during assembly to improve the fit between the 3D-printed components and the purchased hardware. Through iterative testing, we were able to refine the alignment of the servo connector, knee rod, and leg joints so the mechanism could operate more consistently during testing.
Electrical
The electronics system was designed to control the motion of the robot leg using an Arduino, a Servo Power Distribution Board, two push buttons, servos, and connecting wires. The Arduino acted as the main controller for the system by receiving input signals from the buttons and sending output signals to the servos. The Servo Power Distribution Board was used to provide stable power to the servos, allowing them to operate reliably during the walking and jumping motions.
Two buttons were incorporated into the circuit to control the robot’s different motion modes. One button was programmed to activate the walking motion, while the other button was used to activate the jumping motion. When either button was pressed, the Arduino processed the input and triggered the corresponding servo movement sequence. This allowed the robot leg to switch between behaviors in a simple and controlled way.
Wires were used to connect the Arduino, buttons, Servo Power Distribution Board, and servos together. A key challenge during the electronics integration was cable management. Since the robot was mounted on a wooden stand supported by two poles, there were limited areas to hide or secure the wires cleanly. As a result, we had to carefully route the cables around the stand and poles to prevent them from interfering with the moving leg mechanism. Through testing and small adjustments, we organized the wiring so that the electronics remained connected while still allowing the leg to move freely.
This electronics setup worked directly with the code, since the Arduino program interpreted the button inputs and sent the correct signal commands to the servos to perform either the walking or jumping motion.
Arduino Code
#include <Servo.h>
Servo hipServo;
Servo kneeServo;
const int HIP_PIN = 3;
const int KNEE_PIN = 5;
const int JUMP_BUTTON_PIN = 8;
int HIP_HOME = 45;
int KNEE_HOME = 70;
int hipCurrent = HIP_HOME;
int kneeCurrent = KNEE_HOME;
// You currently have 6 phases
const int NUM_JUMP_PHASES = 6;
float hipDelta[NUM_JUMP_PHASES] = {
0, 22.2, -15, 10, 15, 0
};
float kneeDelta[NUM_JUMP_PHASES] = {
0, -25, 45, -10, -15, 0
};
float jumpPercent[NUM_JUMP_PHASES] = {
0, 40, 55, 60, 85, 100
};
int TOTAL_JUMP_TIME = 2200;
float HIP_DIR = -1.0;
float KNEE_DIR = -1.0;
float HIP_SCALE = 1.3;
float KNEE_SCALE = 1.2;
bool hasReturnedHome = true;
void writeLeg() {
hipServo.write(constrain(hipCurrent, 0, 180));
kneeServo.write(constrain(kneeCurrent, 0, 180));
}
float easeInOut(float t) {
return t * t * (3.0 - 2.0 * t);
}
void moveLegSmooth(int hipTarget, int kneeTarget, int durationMs, int steps) {
int hipStart = hipCurrent;
int kneeStart = kneeCurrent;
for (int i = 1; i <= steps; i++) {
float u = (float)i / (float)steps;
float e = easeInOut(u);
hipCurrent = round(hipStart + (hipTarget - hipStart) * e);
kneeCurrent = round(kneeStart + (kneeTarget - kneeStart) * e);
writeLeg();
int stepDelay = max(1, durationMs / steps);
delay(stepDelay);
}
hipCurrent = hipTarget;
kneeCurrent = kneeTarget;
writeLeg();
}
int hipTargetFromDelta(float deltaTheta) {
return constrain(round(HIP_HOME + HIP_DIR * HIP_SCALE * deltaTheta), 0, 180);
}
int kneeTargetFromDelta(float deltaTheta) {
return constrain(round(KNEE_HOME + KNEE_DIR * KNEE_SCALE * deltaTheta), 0, 180);
}
void goHome() {
moveLegSmooth(HIP_HOME, KNEE_HOME, 220, 28);
}
void jumpMotion() {
for (int i = 1; i < NUM_JUMP_PHASES; i++) {
int hipTarget = hipTargetFromDelta(hipDelta[i]);
int kneeTarget = kneeTargetFromDelta(kneeDelta[i]);
int phaseDuration = round(
TOTAL_JUMP_TIME * (jumpPercent[i] - jumpPercent[i - 1]) / 100.0
);
int steps = max(12, phaseDuration / 12);
moveLegSmooth(hipTarget, kneeTarget, phaseDuration, steps);
delay(25);
}
hasReturnedHome = false;
}
void setup() {
hipServo.attach(HIP_PIN);
kneeServo.attach(KNEE_PIN);
pinMode(JUMP_BUTTON_PIN, INPUT_PULLUP);
hipCurrent = HIP_HOME;
kneeCurrent = KNEE_HOME;
writeLeg();
delay(1000);
}
void loop() {
if (digitalRead(JUMP_BUTTON_PIN) == LOW) {
jumpMotion();
// wait until button is released so it does not repeat forever
while (digitalRead(JUMP_BUTTON_PIN) == LOW) {
delay(10);
}
}
if (!hasReturnedHome) {
goHome();
hasReturnedHome = true;
}
}As seen in the arduino code, some angles were toggled slightly from their expected values extracted from the Fusion motion study. This is largely due to physical limitations, as Fusion does not account for gravity or friction.
BOM
Part | Purpose | Quantity | Cost | Vendor |
|---|---|---|---|---|
Cardboard | Range of motion Iteration | 1 | $0 | Personal Supply |
Toothpick | Joints | 4 | $0 | Personal Supply |
3D Printed Capstan Drive | High precision speed reducer | 1 | $0 | Personal Supply |
Capstan DM20 Rope | Link small and large capstan drums | 1 | 22.50 |
|
3D Printed Attachment | Secure Components | 1 | $0 | Personal Supply |
3D Printed Leg | Body Mechanism | 1 | $0 | Personal Supply |
Driving Mechanism | 1 | $44.97 | Amazon | |
Metal Rod | Secure Components | 1 | $0 | RMD Room |
Servo Power supply | to supply power to the servos | 1 | $80 | Personal Supply |
Arduino accelerometer | to get Data from leg tests | 1 | $7 | Personal Supply |
Wood | For the Stand | 1 | $15 | TIW |
Metal Rods | For stand | 2 | $0 | ME Machine Shop Scrap |