Skip to content

A simple simulator of the Student Robotics kit, using PyGame

License

Notifications You must be signed in to change notification settings

HarryCutts/sr-turtle

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Student Robotics Robot Simulator

This is a simple, portable robot simulator developed for Student Robotics, originally for a summer school aimed at 15-18 year olds. It allows competitors to test their code for such things as navigation and item finding while remaining similar to the Student Robotics API which they are using to control their real hardware.

Installing and running

The simulator requires a Python 2.7 installation, the pygame library, PyPyBox2D, and PyYAML.

Pygame, unfortunately, is tricky (though not impossible) to install in virtual environments. It's easiest to use your operating system's package manager. Windows users could use Portable Python. PyPyBox2D and PyYAML are more forgiving, and should install just fine using pip or easy_install.

Once the dependencies are installed, simply run the test.py script to test out the simulator.

Writing and running a program

Keep your programs in the directory containing the simulator files, so that the sr module can be imported.

To run one or more scripts in the simulator, use run.py, passing it the file names. You can also pass it a configuration YAML file with the --config switch, which sets the game to be used and other parameters (such as the number of tokens in a Pirate Plunder game).

An example program can be found in test.py, which implements a simple state machine and does a pretty shoddy job of finding and picking up tokens. To try it, run the following:

$ python run.py test.py

To pit three test robots against one another, pass the script in three times:

$ python run.py test.py test.py test.py

Robot API

The API for controlling a simulated robot is designed to be as similar as possible to the SR API.

Motors

The simulated robot has two motors configured for skid steering, connected to a two-output Motor Board. The left motor is connected to output 0 and the right motor to output 1.

The Motor Board API is identical to that of the SR API, except that motor boards cannot be addressed by serial number. So, to turn on the spot at one quarter of full power, one might write the following:

R.motors[0].m0.power = 25
R.motors[0].m1.power = -25

The Grabber

The robot is equipped with a grabber, capable of picking up a token which is in front of the robot and within 0.4 metres of the robot's centre. To pick up a token, call the R.grab method:

success = R.grab()

The R.grab function returns True if a token was successfully picked up, or False otherwise. If the robot is already holding a token, it will throw an AlreadyHoldingSomethingException.

To drop the token, call the R.release method.

Cable-tie flails are not implemented.

Vision

To help the robot find tokens and navigate, each token has markers stuck to it, as does each wall. The R.see method returns a list of all the markers the robot can see, as Marker objects. The robot can only see markers which it is facing towards.

Each Marker object has the following attributes:

  • info: a MarkerInfo object describing the marker itself. Has the following attributes:
    • code: the numeric code of the marker.
    • marker_type: the type of object the marker is attached to (either MARKER_TOKEN or MARKER_ARENA).
    • offset: offset of the numeric code of the marker from the lowest numbered marker of its type. For example, token number 3 has the code 43, but offset 3.
    • size: the size that the marker would be in the real game, for compatibility with the SR API.
  • centre: the location of the marker in polar coordinates, as a PolarCoord object. Has the following attributes:
    • length: the distance from the centre of the robot to the object (in metres).
    • rot_y: rotation about the Y axis in degrees.
  • dist: an alias for centre.length
  • res: the value of the res parameter of R.see, for compatibility with the SR API.
  • rot_y: an alias for centre.rot_y
  • timestamp: the time at which the marker was seen (when R.see was called).

For example, the following code lists all of the markers the robot can see:

markers = R.see()
print "I can see", len(markers), "markers:"

for m in markers:
    if m.info.marker_type == MARKER_TOKEN:
        print " - Token {0} is {1} metres away".format( m.info.offset, m.dist )
    elif m.info.marker_type == MARKER_ARENA:
        print " - Arena marker {0} is {1} metres away".format( m.info.offset, m.dist )