plankton
Published

RB-0 - Jetson Nano Powered Rover

RB-0 is a hobby sized rover that uses the same suspension concept as NASA's newer differential-bar rovers. It uses a Jetson Nano + camera.

IntermediateProtip5 hours6,670
RB-0 - Jetson Nano Powered Rover

Things used in this project

Hardware components

Metal gear servos x 8
×1
360 degree servos x 6
×1
5mm linear bearing
×1
5mm shaft collar
×1
5mm shaft
×1
Servo driver
×1
Servo extender
×1
Flex cable
×1
Camera Module
Raspberry Pi Camera Module
×1
Wide angle lens
×1
transformer
×1
battery
×1
DC to DC cord
×1
DC to USB
×1
Jumper wires (generic)
Jumper wires (generic)
×1
antenna
×1
wi-fi
×1
jumper cap
×1
Actuonix l12
×1

Software apps and online services

jet bot image

Hand tools and fabrication machines

m2 allen key

Story

Read more

Custom parts and enclosures

Thingiverse files

STLs and inside wiring pictures

Schematics

screen_shot_2020-03-08_at_11_29_54_am_UkaHdawyGu.png

screen_shot_2020-03-08_at_11_30_02_am_uZIguHlyZP.png

screen_shot_2020-03-08_at_11_30_16_am_EVIzEofv4E.png

img_0985_YalCdJs20t.HEIC

2 bearings per shaft, 2 shaft collars per shaft

img_2173_vfOLxRmP0Q.HEIC

insert shaft collar into designated slot

img_9025_VqWjCDNMBu.HEIC

legs spin on shaft with bearings

Inside wiring

Too many components weren't on frizzing, but these photos should help.

Code

basic_motion.py

Python
I ran this in a Jupiter Python Notebook
import time
from board import SCL, SDA
from busio import I2C
from adafruit_pca9685 import PCA9685
from adafruit_motor import servo
import Jetson.GPIO as GPIO
import ipywidgets.widgets as widgets
from IPython.display import display
import traitlets
from jetbot import Camera, bgr8_to_jpeg

i2c_bus = I2C(SCL, SDA)
pca = PCA9685(i2c_bus)
pca.frequency = 50

camera_tilt = servo.Servo(pca.channels[6], min_pulse=500, max_pulse=2600, actuation_range=180)
camera_pan = servo.Servo(pca.channels[7], min_pulse=500, max_pulse=2600, actuation_range=180)
camera_z = servo.Servo(pca.channels[8], min_pulse=500, max_pulse=2600, actuation_range=180)

frnt_rw = servo.ContinuousServo(pca.channels[0])
frnt_rs = servo.Servo(pca.channels[1], min_pulse=500, max_pulse=2600, actuation_range=180)

mid_rw = servo.ContinuousServo(pca.channels[2])
mid_rs = servo.Servo(pca.channels[3], min_pulse=500, max_pulse=2600, actuation_range=180)

back_rw = servo.ContinuousServo(pca.channels[4])
back_rs = servo.Servo(pca.channels[5], min_pulse=500, max_pulse=2600, actuation_range=180)

back_lw = servo.ContinuousServo(pca.channels[9])
back_ls = servo.Servo(pca.channels[10], min_pulse=500, max_pulse=2600, actuation_range=180)

mid_lw = servo.ContinuousServo(pca.channels[11])
mid_ls = servo.Servo(pca.channels[12], min_pulse=500, max_pulse=2600, actuation_range=180)

frnt_lw = servo.ContinuousServo(pca.channels[13])
frnt_ls = servo.Servo(pca.channels[14], min_pulse=500, max_pulse=2600, actuation_range=180)

r_wheels = [frnt_rw, mid_rw, back_rw]
l_wheels = [frnt_lw, mid_lw, back_lw]
a_wheels = [frnt_lw, mid_lw, back_lw, frnt_rw, mid_rw, back_rw]

    

a_steer = [frnt_rs, mid_rs, back_rs, frnt_ls, mid_ls, back_ls]

def para():
    frnt_rs.angle = 85
    mid_rs.angle = 100
    back_rs.angle = 110

    frnt_ls.angle = 75
    mid_ls.angle = 90
    back_ls.angle = 85
    time.sleep(.5)
    

camera_tilt.angle = 90
camera_pan.angle=90

def go(change):
    
    para()
    time.sleep(.2)
    for wheel in r_wheels:
        wheel.throttle = -1
    for wheel in l_wheels:
        wheel.throttle = 1
    time.sleep(3)
    for wheel in a_wheels:
        wheel.throttle=0
        
def backwardo(change):
    
    para()
    time.sleep(.2)
    for wheel in r_wheels:
        wheel.throttle = 1
    for wheel in l_wheels:
        wheel.throttle = -1
    time.sleep(3)
    for wheel in a_wheels:
        wheel.throttle=0   

def tilt_plus(change):
    if camera_tilt.angle <= 170:
        camera_tilt.angle +=20
def tilt_minus(change):
    if camera_tilt.angle >= 10:
        camera_tilt.angle -= 10
def pan_plus(change):
    if camera_pan.angle <= 170:
        camera_pan.angle += 10
def pan_minus(change):
    if camera_pan.angle >= 10:
        camera_pan.angle -= 10
def stop(change):
    camera_pan.angle = 90
    camera_tilt.angle = 90
    para()
    
def perp_plus(change):
    frnt_rs.angle=0
    mid_rs.angle=10
    back_rs.angle=20

    frnt_ls.angle=160
    mid_ls.angle=180
    back_ls.angle=175
    time.sleep(.5)
    
    for wheel in r_wheels:
        wheel.throttle = 1
    for wheel in l_wheels:
        wheel.throttle = 1
    time.sleep(3)
    for wheel in a_wheels:
        wheel.throttle=0
        
def perp_min(change):
    frnt_rs.angle=0
    mid_rs.angle=10
    back_rs.angle=20

    frnt_ls.angle=160
    mid_ls.angle=180
    back_ls.angle=175
    time.sleep(.5)
    
    for wheel in r_wheels:
        wheel.throttle = -1
    for wheel in l_wheels:
        wheel.throttle = -1
    time.sleep(3)
    for wheel in a_wheels:
        wheel.throttle=0
```

### Attach functions to events

#Another way to use traitlets, is by attaching functions (like ``forward``) to events.  These
#functions will get called whenever a change to the object occurs, and will be passed some information about that change
#like the ``old`` value and the ``new`` value.  

#Let's create and display some buttons that we'll use to control the robot.



# create buttons
button_layout = widgets.Layout(width='80px', height='60px', align_self='center')
stop_button = widgets.Button(description='90', button_style='danger', layout=button_layout)
forward_button = widgets.Button(description='tilt+', layout=button_layout)
backward_button = widgets.Button(description='tilt-', layout=button_layout)
left_button = widgets.Button(description='pan+', layout=button_layout)
right_button = widgets.Button(description='pan-', layout=button_layout)
another_right = widgets.Button(description='right', layout=button_layout)
another_left = widgets.Button(description='left', layout=button_layout)
another_top = widgets.Button(description='forward', layout=button_layout)
another_bottom = widgets.Button(description='backward', layout=button_layout)
lateral_right = widgets.Button(description='lat+', layout=button_layout)
lateral_left = widgets.Button(description='lat-', layout=button_layout)
z_up = widgets.Button(description='z-up', layout=button_layout)
z_dwn = widgets.Button(description='z-dwn', layout=button_layout)

# display buttons
middle_box = widgets.HBox([left_button, stop_button, right_button], layout=widgets.Layout(align_self='center'))
top_box = widgets.HBox([another_left, forward_button, another_right], layout=widgets.Layout(align_self='center'))
bottom_box = widgets.HBox([lateral_left, backward_button, lateral_right], layout=widgets.Layout(align_self='center'))
controls_box = widgets.VBox([another_top, top_box, middle_box, bottom_box, another_bottom])
display(controls_box)
```


    VBox(children=(Button(description='forward', layout=Layout(align_self='center', height='60px', width='80px'), 


#You should see a set of robot controls displayed above!  But right now they wont do anything.  To do that
#we'll need to create some functions that we'll attach to the button's ``on_click`` event.  

#Now that we've defined the functions, let's attach them to the on-click events of each button


# link buttons to actions
stop_button.on_click(stop)
forward_button.on_click(tilt_minus)
backward_button.on_click(tilt_plus)
left_button.on_click(pan_plus)
right_button.on_click(pan_minus)
another_top.on_click(go)
another_bottom.on_click(backwardo)
lateral_right.on_click(perp_plus)
lateral_left.on_click(perp_min)
```

#Now when you click each button, you should see the robot move!


camera = Camera.instance(width=224, height=224)

image = widgets.Image(format='jpeg', width=400, height=400)  # this width and height doesn't necessarily have to match the camera

camera_link = traitlets.dlink((camera, 'value'), (image, 'value'), transform=bgr8_to_jpeg)

display(image)
```


    Image(value=b'\xff\xd8\xff\xe0\x00\x10JFIF\x00\x01\x01\x00\x00\x01\x00\x01\x00\x00\xff\xdb\x00C\x00\x02\x01\x0

Credits

plankton

plankton

3 projects • 14 followers

Comments