Here is simple example creating a client for the API and getting the robot green1 kicking:
import rsk with rsk.Client() as client: client.green1.kick()
import rskimports the relevant Python package
withstatement ensures that the client will be properly closed at the end of the session. Especially, it forces the robots to stop moving at the end of the program.
client.green1.kick()asks the robot
When creating a client, you can also provide the following arguments:
import rsk with rsk.Client(host='127.0.0.1', key='') as client: client.robots['green'].kick()
hostis the IP address of the computer running the Game Controller
keyis the team access key (by default, blank) that can be set in the Game Controller to prevent a team from controlling opponents robots
Robots can be accessing using the following syntax:
# Shortcuts to access a robot client.green1 client.green2 client.blue1 client.blue2 # Full syntax allowing dynamic access client.robots['green'] client.robots['green'] client.robots['blue'] client.robots['blue']
Localization is polled using a thread and can be continuously accessed through the following variables:
# Robot position (x [m], y [m]): client.green1.position # Robot orientation (theta [rad]): client.green1.orientation # Position + orientation (x [m], y [m], theta [rad]) client.green1.pose # Ball's position (x [m], y [m]) client.ball
The field frame is detailed in the coordinates and markers section
Note: arrays are numpy array
rsk.constants provide some useful constants (field dimensions, rules limitations etc.):
from rsk import constants # Field length (x axis) constants.field_length # Field width (y axis) constants.field_width # Goal width constants.goal_width # Side of the (green) border we should be able to see around the field constants.border_size
See more constants in the source file.
Controlling the robots
To control the robots, you can use the following functions:
# Kicks, takes an optional power parameter between 0 and 1 robot.kick() # Controls the robots in its own frame, arguments are x speed [m/s], # y speed [m/s] and rotation speed [rad/s] # Go forward, 0.25 m/s robot.control(0.25, 0., 0.) # Rotates 30 deg/s counter-clockwise robot.control(0., 0., math.radians(30))
If a command fails, a
rsk.ClientError exception will be raised. You can catch it using:
try: robot.kick() robot.control(0.1, 0, 0) except rsk.ClientError: print('Error during a command!')
Such an exception will also happen if the robot you want to control was preempted by the Game Controller.
You can also use the
goto method to send the robot to an arbitrary position on the field:
# Sending a robot to x=0.2m, y=0.5m, theta=1.2 rad robot.goto((0.2, 0.5, 1.2))
Sends the robot to the position
theta=1.2 on the field.
You can use the second argument of
goto (which is
wait, a boolean value) to tell goto not to
block the execution of the program. This way, you can do something else at the same time without threading.
Here is an example placing two robots:
# Placing two robots, the loop will block until both robots are placed arrived = False while not arrived: robot_1_arrived = client.green1.goto((0.2, 0.3, 0.), wait=False) robot_2_arrived = client.green2.goto((0.2, -0.3, 0.), wait=False) arrived = robot_1_arrived and robot_2_arrived
The second argument of
goto is a boolean (
True, the call to
block the execution of the program until the robot reaches its destination. When
goto call will return immediately, after updating the instant velocity of the controlled robot, and return
True if the robot reached,
If you want to run some code everytime new information is obtained from the detection, you can register
a method with the
on_update field in
def print_the_ball(client, dt): print(client.ball) # This will print the ball everytime a new information is obtained from the client client.on_update = print_the_ball
This can be convenient if you want to log data for further analysis, because you will log all information exactly once, and once it is received.