Intrepid Ramp Robot Part 1: steering
Dec 2023
GOAL: build a robot that can climb up a wooden ramp with a 22 degree incline
SKILLS: CAD (OnShape), HTML programming, python programming, Flask, HTTP request handling, server-client wifi communication, wiring, assembly, laser cutting, prototyping, testing, PWM motor control, use of single board computer (Raspberry Pi), design, collaboration
This robot is an electronics project that I did with 2 of my friends
Task: build a robot that can travel up a ramp, controlled remotely
Design constraints:
should fit in a circle 45 cm in diameter.
less than 30 cm tall.
able to ascend the ramp without falling off the side.
no touching your robot during its movement
cannot use an RC car controller (should be controlled through wifi from a laptop or phone)
cannot fly
Our robot travels up the ramp, and steers by slowly reversing one wheel at a time.
Fabrication
chassis: laser cut plywood
wheels: 3D printed with 3 pololu wheel treads
motor holders: 3D printed
castor wheel base: 3D printed
fasteners: bolts and nuts, zip ties, tape
Additional parts: L298N motor driver, Raspberry Pi, 5V power bank, 9V battery, castor wheel,
I worked on the app.py code, mapping the framework, designing the wheels and chassis, CADing the castor wheel base, modifying the motor holders, wiring the electronics, and CADing the existing parts like the batteries and boards in to plan sizing and hole placement. Throughout the project, we brainstormed, designed, and troubleshot the robot collaboratively!
app.py Code
# app.py
# ME30 P5 2023
from flask import Flask, render_template, request
app = Flask(__name__)
import RPi.GPIO as GPIO
import time
# Set up GPIO pins
GPIO.setmode(GPIO.BOARD)
# Define GPIO pins connected to the H-bridge inputs
motorL = 11 #blue
motorR = 16 #red
motorLB = 13 #blue
motorRB = 15
# Set up PWM for forward rotation
GPIO.setup(motorL, GPIO.OUT)
GPIO.setup(motorR, GPIO.OUT)
pwm_motorL = GPIO.PWM(motorL, 500) # 500 Hz frequency
pwm_motorR = GPIO.PWM(motorR, 500)
# Start PWM at 0
pwm_motorL.start(0)
pwm_motorR.start(0)
# Set up PWM for backwards rotation
GPIO.setup(motorLB, GPIO.OUT)
GPIO.setup(motorRB, GPIO.OUT)
pwm_motorLB = GPIO.PWM(motorLB, 500)
pwm_motorRB = GPIO.PWM(motorRB, 500)
pwm_motorLB.start(0)
pwm_motorRB.start(0)
#define routes for webpage
@app.route('/')
def index():
return render_template('index.html')
@app.route('/control/left')
def controlleft():
pwm_motorL.ChangeDutyCycle(0)
pwm_motorR.ChangeDutyCycle(0)
time.sleep(0.05)
# set to 20% duty cycle: slow
pwm_motorLB.ChangeDutyCycle(20)
pwm_motorRB.ChangeDutyCycle(0)
print('Left command received')
time.sleep(0.05) # Run for 0.05 seconds
# Stop the motors
pwm_motorL.ChangeDutyCycle(0)
pwm_motorR.ChangeDutyCycle(0)
time.sleep(0.1)
pwm_motorLB.ChangeDutyCycle(0)
pwm_motorRB.ChangeDutyCycle(0)
print('Left command complete')
return 'left done'
@app.route('/control/right')
def controlright():
pwm_motorL.ChangeDutyCycle(0)
pwm_motorR.ChangeDutyCycle(0)
time.sleep(0.05)
pwm_motorLB.ChangeDutyCycle(0)
pwm_motorRB.ChangeDutyCycle(20)
print('Right command received')
time.sleep(0.05)
pwm_motorL.ChangeDutyCycle(0)
pwm_motorR.ChangeDutyCycle(0)
time.sleep(0.1)
pwm_motorLB.ChangeDutyCycle(0)
pwm_motorRB.ChangeDutyCycle(0)
print('Right command complete')
return 'right done'
@app.route('/control/forward')
def controlfor():
# set to 80% duty cycle: fast
pwm_motorL.ChangeDutyCycle(80)
pwm_motorR.ChangeDutyCycle(80)
time.sleep(0.1)
pwm_motorLB.ChangeDutyCycle(0)
pwm_motorRB.ChangeDutyCycle(0)
print('Forward command received')
return 'forward on'
@app.route('/control/stop')
def controlstop():
pwm_motorL.ChangeDutyCycle(0)
pwm_motorR.ChangeDutyCycle(0)
pwm_motorLB.ChangeDutyCycle(0)
pwm_motorRB.ChangeDutyCycle(0)
print('stopped')
return 'stopped'
if __name__ == '__main__':
app.run(host='0.0.0.0', port=80, debug=True)
index.html Code
<!--index.html, ME30 P5-->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Car Controller</title>
<!-- Include jQuery from a CDN -->
<script src="https://code.jquery.com/jquery-3.6.4.min.js"></script>
</head>
<body>
<div style="text-align: center; margin-top: 50px;">
<h1>Car Controller</h1>
<button id="leftButton">Left</button>
<button id="forwardButton">Forward</button>
<button id="rightButton">Right</button>
<button id="stopButton">Stop</button>
<script>
// Function to send a GET request to the specified endpoint
function sendRequest(endpoint) {
$.ajax({
type: "GET",
url: "http://10.243.87.126:5000/" + endpoint,
success: function(data) {
console.log("Request successful:", data);
},
error: function(error) {
console.error("Error:", error);
}
});
}
// Attach click event handlers to the buttons
$("#leftButton").on("click", function() {
sendRequest('control/left');
});
$("#forwardButton").on("click", function() {
sendRequest('control/forward');
});
$("#rightButton").on("click", function() {
sendRequest('control/right');
});
$("#stopButton").on("click", function() {
sendRequest('control/stop');
});
</script>
</body>
</html>