Jetson Nano + Sphero RVR Mash-up (PART 2)

Pages
Contributors: D___Run___
Favorited Favorite 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!

Note: You will need to re-enter the `sudo chmod 660 /dev/ttyTHS1` command every time you power cycle your NVIDIA Jetson Nano so that Jupyter Notebooks has propper permissions to the UART port. If you are getting a "Permission Denied" error, please open a terminal prompt and enter the mentioned command.

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!

Note: As your robot moves further and further away from your WiFi router you will notice more and more lag in both the camera feed and its response you pressing buttons!

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?