SAFAR Scripting: the missing link between MRDS and roboticists

Microsoft Robotics Developer Studio and Visual Studio provide an excellent platform for robotics software development. However, its complexity makes it almost impossible for non-professional programmers.

Many roboticists come from other professional disciplines and have basic programming skills. They cannot deal with the complexity of the Visual Studio IDE and the CCR and DSS architecture of MRDS. But they would like to write simple programs using variables and control statements such as if-then-else, for-next, do-while, etc. to control robot behavior and navigation.

With the intention of filling this gap, we added a Scripting Engine to SAFAR. The programming language chosen for it is IronPython, an implementation of the Python dynamic language for the .NET framework.

The SAFAR IronPython Scripting Engine in the Route Following service

At this stage of SAFAR, the IP Scripting Engine is used in the Route Following service. More services will use this technique in future versions.

In earlier versions of SAFAR, the navigation algorithm (‘follow-the-carrot’ or ‘straight to waypoint’ modes) was hardcoded into the RF service and could not be changed by end users (it was possible to modify only some parameters in the RF window). The RF service executed the algorithm every time it received a notification from the GPS service (e.g every 50 ms)

Now, the algorithm is not executed by the RF service directly, but by the Scripting Engine embedded in it. Thus, instead of executing any navigation algorithm, every time the RF service receives GPS data, it calls (via the scripting engine) the ‘’ script, which is available to be modified by end users! (the file is in the ‘…safar/scripts’ folder).

You can modify or create your own ‘’ script by editing it with some IronPython Editor or simply with Notepad.

The Scripting Engine exposes RF variables and functions that are needed to write a script. For example, the position given by the GPS is exposed as rf.gpsx and rf.gpsy (in UTM coordinates). There are also functions that are not needed, but that you can find useful, like ‘ClosestPointInSegment’ or ‘LineSegmentIntersection’.

The following list shows all variables and functions exposed that you should use to write a script:

It is set to zero every time you press the “play” button in the RF window and it is incremented by one every time the RF service receives new GPS data and runs the script.

rf.gpsx, rf.gpsy
UTM coordinates sent by the GPS device.

rf.gpsx_prev, rf.gpsy_prev
UTM coordinates sent by the GPS in the previous step.

Maximum steering angle of selected robot
Proportional Gain parameter that appears in the Config tab of the Route Following window

Percentage of the waypoint speed at which the vehicle will move when it turns with maximum steering angle (also in Config tab) 

Lookahead distance away from the vehicle center at which the carrot lies (also in Config tab)

Array of waypoints that make up the route. You can access all properties for each waypoint:

Current waypoint of the route

This function checks if current waypoint is reached. If so, rf.CurrentWaypoint in incremented by one.

This function returns the closest point to the point (x,y) on the segment joining the points a and b.

Tests the intersection between the segment joining the points a,b and the circle of radius r centered at cx,cy. It returns two intersection points and a boolean value indicating if intersection exists.

rf.SetSteering(speed, steeringAngle)
Sets the speed (m/s) and steering angle (radians) of the robot.

rf.RotationalDifference(heading, x, y, x_target, y_target)
Returns the shortest angle that a robot should rotate to stay pointing at a given target point. Positive values indicate anti-clockwise rotations. The obtained value is always in the range (-PI, +PI).
Parameters are:
heading: current robot orientation angle
x, y: current robot location
x_target, y_target: target point coordinates