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:

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>