PupperPy

Codename: CERBARIS

Our build and extension of the Stanford Pupper Robot. Codename: C.E.R.B.A.R.I.S.


Project maintained by campusrover Hosted on GitHub Pages — Theme by mattgraham

Introduction | Team | Hardware | Software Overview | Software Setup | Computer Vision | Collision Avoidance | Web Interface | Odometry | Behavioral Control |

Basic Pupper Software

The Pupper robot operates by using a PS4 controller to send commands to the robot via bluetooth.To do this it utilizes the following 4 repositories from Stanford Robotics Club:

UDPComms

This package is central to how the robot communicates between asynhronously running parallel processes. This package functions through the use of Sockets and functions by setting up Server (UDPComms.Publisher) and Client (UDPComms.Subscriber) sockets on a local ethernet port facilitating one-way communication. Both the Publisher and Subscriber must be created before a message is sent or read, and if either end of the communication path is closed then both must be re-created. To use UDPComms, the local ethernet, eth0, must be set to static IP 10.0.0.255.

Example usage of UDPComms:

from UDPComms import Publisher, Subscriber, timeout
pub = Publisher(1234)
sub = Subscriber(1234)

msg = {'name': 'John', 'height': 172}
pub.send(msg)
msg2 = {'name': 'Mary', 'height': 160}
pub.send(msg)

try:
    recevied = sub.get()
except timeout:
    received = None

The above code would result in received being {'name': 'Mary', 'height': 160} since that was the last message sent. The Publisher adds messages to a first-in-last-out stack and the Subscriber pops the top message from the stack. Calling sub.get() again would return John’s information. UDPComms sends messages by first converting them to bytes, so any object that can be reliably converted into bytes can be sent via UDPComms.

PS4Joystick

This library handles connection and communcation with a PS4 controller via bluetooth. This is handled through the Joystick object which when instantiated will wait for a PS4 controller to connect. The PS4 controller can be paired by holding the share and power buttons at the same time until you see a double-blinking white light.

Example:

from PS4Joystick import Joystick
joystick = Joystick()
joystick.led_color(red=0, blue=0, green=255)
values = joystick.get_input()

The get_input() command will return a dictionary representing the current state of the controller.

Keys:

PupperCommand

This repository houses the joystick.py script which run a loops that periodically queries the PS4 joystick and reformats the command to send to the Pupper robot command loop via UDPComms channel 8830. This can be run directly as python script or via a UNIX background service.

StanfordQuadruped

This project contains the code that actually controls to robot’s movement, chooses it’s gait and behavior and sends PWM signals to the servos. This is all carried out by the execution of the run_robot.py script. This script initalizes and maintains 4 important objects:

This process can be run directly as a python script or run as a background unix service. See Software Setup to see how to setup and run this.

Our Automated Control Software

In order to take programatic control of the Pupper robot we replaced the function of the PupperCommand joytick.py script with our own pupperpy.CommandInterface.Control object.

If pupperpy is installed with sudo pip3 then all necessary processes for robot operation can be run with sudo python3 /path/to/PupperPy/pupperpy/run_cerbaris.py

The pupperpy Control interface

Unlike the joystick script, our controller is an object that is instantiated and is then run. When created the Control object creates:

On every iteration of the loop the _step() function checks the joystick for activation (L1) or emergency stop (L2) commands, otherwise it uses update_behavior() to check sensor data and update movement commands and then sends those to both the run_robot script and to the web interface.

Additionally, this interface simplfies the creation of new behaviors through the use of simplified movement commands:

control.move_forward()  # moves forward at max safe velocity
control.move_backward() # moves backward at max safe velocity
control.move_stop()     # stops forward and backward movement

control.turn_left()     # turns left
control.turn_right()    # turns right
control.turn_stop()     # stops turning

control.activate()      # Activates robot, initializes motor positions
control.start_walk()    # switches robot gait from REST to TROT
control.stop_walk()     # switches robot gait from TROT to REST

One can simply extend the control object and override the update_behavior function in order to implement new behavior. The existing behavior is very simple.