Jetson Nano + Sphero RVR Mash-up (PART 2)
Example 2: Teleoperation
With the NVIDIA Jetson Nano and the Sphero RVR now communicating and functioning properly it is now time to work on integrating the RVR SDK library into a few of the JetBot examples that come on the JetBot image with a few changes. Again, we have already made a few of these changes and saved them in the RVR Examples Notebooks. This example looks at controlling the motors of the RVR and driving it remotely using a few buttons and a live video feed from the camera.
Before running this example make sure that you shutdown the previous camera test example by opening the list of all Kernels that are running and click “Shutdown” next to any other Kernels that are running. We do this because only one Python Notebook can be using the camera at a time.
Open the remote_drive.ipynb
and run the script.
After a moment an interface should appear with a live video feed and a few buttons for direction driving. You should be able to click on a given button and the robot will either pivot in that direction or drive forward / reverse. Note that the RVR doesn’t continually drive, but will stop after about two seconds. This is part of the RVR SDK that has a timeout for any driving functions after 2 seconds.
Go ahead and play and drive your RVR around… chase your cat, your kids, or sneak up on your mom!
But, wait... My RVR moves when I press the button and then stops after a bit?!
Yes, this is completely normal and is a built in timeout programmed into the RVR SDK that when you run a motor, it will only run for 2 seconds before stopping!
Code to Note
Like our other script we import all of the required packages. Note that we have added the Sphero RVR SDK to the import list in this script.
language:python
import os
import sys
import time
import ipywidgets.widgets as widgets
from IPython.display import display
import traitlets
from jetbot import Camera
from jetbot import bgr8_to_jpeg
from sphero_sdk import SpheroRvrObserver
Like Example 1 we instantiate the camera object and the image widget. In addition to that we also instantiate the RVR object and then send a command to the RVR to wake up and be ready to accept other commands.
language:python
camera = Camera.instance()
image = widgets.Image(format='jpeg', width=300, height=300)
rvr = SpheroRvrObserver()
rvr.wake()
Again, we link the camera feed to the image widget for telepresence of what our bot is seeing.
language:python
camera_link = traitlets.dlink((camera, 'value'), (image, 'value'), transform=bgr8_to_jpeg)
Next, to be able to control our robot in a telepresence type project we need inputs to be able to tell the robot to go one direction or another. We do this through creating an interface of button widgets in Jupyter Notebooks. We define those buttons below.
language:python
# create buttons
button_layout = widgets.Layout(width='100px', height='80px', align_self='center')
stop_button = widgets.Button(description='stop', button_style='danger', layout=button_layout)
forward_button = widgets.Button(description='forward', layout=button_layout)
backward_button = widgets.Button(description='backward', layout=button_layout)
left_button = widgets.Button(description='left', layout=button_layout)
right_button = widgets.Button(description='right', layout=button_layout)
We then display all of our buttons and our live camera feed.
language:python
# display buttons
middle_box = widgets.HBox([left_button,image, right_button], layout=widgets.Layout(align_self='center'))
controls_box = widgets.VBox([forward_button, middle_box, backward_button,stop_button])
display(controls_box)
The buttons have event handlers attached to them, meaning that we can attach a function to run when the button is pressed. We define those functions here.
language:python
def stop(change):
rvr.raw_motors(
left_mode=0,
left_speed=0, # Valid speed values are 0-255
right_mode=0,
right_speed=0 # Valid speed values are 0-255
)
def step_forward(change):
print("fire")
rvr.raw_motors(
left_mode=1,
left_speed=64, # Valid speed values are 0-255
right_mode=1,
right_speed=64 # Valid speed values are 0-255
)
time.sleep(.5)
rvr.raw_motors(
left_mode=0,
left_speed=0, # Valid speed values are 0-255
right_mode=0,
right_speed=0 # Valid speed values are 0-255
)
def step_backward(change):
rvr.raw_motors(
left_mode=2,
left_speed=64, # Valid speed values are 0-255
right_mode=2,
right_speed=64 # Valid speed values are 0-255
)
time.sleep(.25)
rvr.raw_motors(
left_mode=0,
left_speed=0, # Valid speed values are 0-255
right_mode=0,
right_speed=0 # Valid speed values are 0-255
)
def step_left(change):
rvr.raw_motors(
left_mode=2,
left_speed=128, # Valid speed values are 0-255
right_mode=1,
right_speed=128 # Valid speed values are 0-255
)
time.sleep(.25)
rvr.raw_motors(
left_mode=0,
left_speed=0, # Valid speed values are 0-255
right_mode=0,
right_speed=0 # Valid speed values are 0-255
)
def step_right(change):
rvr.raw_motors(
left_mode=1,
left_speed=128, # Valid speed values are 0-255
right_mode=2,
right_speed=128 # Valid speed values are 0-255
)
time.sleep(.25)
rvr.raw_motors(
left_mode=0,
left_speed=0, # Valid speed values are 0-255
right_mode=0,
right_speed=0 # Valid speed values are 0-255
)
Finally, we attach our defined functions to their constituent button events.
language:python
forward_button.on_click(step_forward)
backward_button.on_click(step_backward)
left_button.on_click(step_left)
right_button.on_click(step_right)
stop_button.on_click(stop)
Operation and Closing
With that you can now drive your RVR + Nano bot around remotely through Jupyter Notebooks. As you play around with this example as a starting point think about how you can add more to your dashboard in terms of sensor values or controlling different parts of RVR... maybe an option to change the colors of the LEDs when you click a button?