Coding With the Sandbox

This section will describe all the features of the Sandbox and provide examples of how to start writing your own programs inside the sandbox.

Toddler in the Sandbox

Your code will reside inside a file named toddler.py. This file must be directly created in your home folder /home/student/toddler.py. Note that you can simply start by copying the default one available at: /usr/local/bin/toddler.py.

Minimal Example Structure

#!/usr/bin/env python import time import numpy import cv2 class Toddler: def __init__(self, IO): print('[Toddler] I am toddler playing in a sandbox') self.camera = IO.camera.initCamera('pi', 'low') self.getInputs = IO.interface_kit.getInputs self.getSensors = IO.interface_kit.getSensors self.mc = IO.motor_control self.sc = IO.servo_control def control(self): print('{}\t{}'.format(self.getSensors(), self.getInputs())) time.sleep(0.05) def vision(self): image = self.camera.getFrame() self.camera.imshow('Camera', image) time.sleep(0.05)

To break this down, the toddler.py must define a class called Toddler:

class Toddler:

This class must have an initialiser that takes and instance of the IO tools as an argument:

def __init__(self,IO):

The IO tools get initialised by the Sandbox and passed onto the Toddler class. We store the instance in a member variable self.IO so it can be used within the class later.

The toddler class must also define two callback functions:

def Control(self):

and

def Vision(self):

Each of these callbacks runs on a separate thread. You can block one of them with time.sleep() command or with computation without stopping the other. If you pass data between these two threads, you need to pay attention to data integrity and synchronisation (mutex).

The both callback functions Control() and Vision() are actually run in a loop within the Sandbox. When the callback ends (returns), it will be then re-called again and again. The Sandbox is responsive for stopping these loops when the program terminate.

Understanding IO Tools

The IOTools class gets instantiated/initialised by the Sandbox. DO NOT CREATE AN INSTANCE OF THIS CLASS YOURSELF!

Note that if you need more precision about the API, don't hesitate to directly take a look to the file located on the Raspberry at: /urs/local/bin/iotools.py.

DC Motor Speed Control

The Direct Current lego motors are directly controlled in velocity (through applied voltage) by the motor board.

Servo-Motor Position Control

The servo-motor connected to the Phidget AdvancedServo board is controlled in position with following methods:

The servo can be powered up/down using the engage() and disengage() methods. Servo will only move when it is engaged. When the servo is engaged, it will actively maintain it's position. This will draw power. When the servo is not loaded (no/little torque is applied on its axle) it will maintain it's position due to the friction in gearbox anyway.

Read Sensors

How to read the sensor data captured by the Phidget Interface Kit board. The Interface Kit keeps track of states of analogue sensors (IR, light) and digital/binary sensors (switches, whiskers, hall effect). You can retrieve the current state of these sensors as array using getSensors() and getInputs():

The sensor values may get updated at high frequency. If you are looking for a short activation, you will have to call this function more often (e.g. in a loop with a short sleep delay). We do NOT recommend relying on signals of short duration though. With other code running on the Raspberry, it will become difficult to reliably detect if the signal appeared or not. The hardware and the interfaces have not been designed for high frequency signal processing.

Image Capture And Image Display