6 Working with simulators

In many situations, robot programs may be developed in a simulator and then transfered to a physical equivalent of the simulated robot capable of operating in the real world.

As with computer games, robot simulators come with physics engines that affect how different ‘physical’ objects in the simulator interact with each other or the state of the world.

Sometimes, the way that ‘physics’ works in the simulator may differ to the way we expect things to work in the real world.

If your robot is behaving in an unexpected way in the simulator, it may be that your program is incorrect, or it may be that the robot is following the program correctly, but you have misunderstood the physics that define the simulated world the robot is operating in.

So let’s consider two areas where we need to understand how the simulated world works so that we can better understand – and better be able to debug – the behaviour of our simulated robot.

6.1 The question of time

You may be familiar with the principle of animation whereby multiple image frames are displayed one after each other in quick succession to give the appearance of motion of figures displayed in the image.

The robot simulator works in a similar way. In the case of nbev3devsim, the simulator is intended to display updates to the world at a rate 30 frames per second (30 fps).

Between the display of each updated frame, an event loop runs that does several things. For example:

  • it checks the state of the robot’s sensors

  • it checks the current and desired state of the motors (for example, how fast and in what direction they are currently turning, or how fast and in what direction the program wants them to turn)

  • it updates the location of the robot based on the state of the motors

  • it checks which part of the program is currently executing.

This suggests that two sorts of time are in play. The first sort of time is the ‘wall clock’ time returned if the robot asks the underlying computer what time it is:

from datetime import datetime

datetime.now()
# Year, month, day, hour, minute, second, microsecond

The second sort of time is the simulator clock time, represented as a count of the number of event loop iterations (rendered at a speed of 30 per second, ideally) that have completed since the simulator started running. Typically, the clock might be reset to zero each time you start a program running in the simulator. Nominally, we might hope that the two sorts of time stand in a known relationship to each other. For example, given that 1/30 fps = 0.033 s, suppose we start our program running at 7pm exactly:

Simulator clock

Anticipated wall clock

0

19:00:00.000

1

19:00:00.033

2

19:00:00.067

Depending on how the simulator is implemented, if the event loop runs once every 1/30 seconds (one second divided by the frame rate) then the program can make reference to the wall clock and the two flavours of time shouldn’t interfere.

However, if for some reason the event loop takes longer than 1/30 s to execute, odd things may happen if you try to use wall clock time in your program. Suppose that the event loop takes 1/20 s to execute:

Simulator clock

Anticipated wall clock

Actual wall clock

0

19:00:00.000

19:00:00.000

1

19:00:00.033

19:00:00.050

2

19:00:00.067

19:00:00.100

As another example, imagine the extreme case of the event loop taking 1 minute to calculate. Suppose you try to turn the motors on for ten seconds of wall clock time. If it’s 19:00:00.0 when the program starts and the robot says: turn the motors on until 19:00:10.0, then the robot won’t have much chance to travel if the event loop doesn’t finish doing its sums for the first frame until 19:01:00.0.

DO

Try to avoid using time-based constructions such as .on_for_seconds() or time-based ‘blocking’ statements such as time.sleep(). Instead, try to use statements that respond to other changes in the state of the world, such as sensor values or motor/wheel rotation counts.

Note: some of the early activities may use time-based constructions to help you develop your understanding of how the various commands work and how to construct simple programs, as well as demonstrate some of the limitations of time-based operations. This is like being shown how to eat with your fingers before being introduced to cutlery!

Also note: in some examples, you may notice that we sometimes need to ensure that real time does ‘move forward’ when running a loop in a simulator program; we do this by adding a short time.sleep() duration to the body of a loop to prevent the simulator Python engine getting stuck in an infinite loop.

DON’T

In later notebooks particularly, try to avoid using time.sleep() or .on_for_seconds() style constructions wherever possible unless you are adding ‘time friction’ to a loop so that it does not get stuck in an infinite loop. Generally, ask yourself the question: what event or situation do I actually want my robot to wait for?

6.2 The question of mass

What do you think happens to the speed of a robot in the real world if you tell it to drive at a particular speed?

# Run this cell to display a simple interactive multiple choice question
from multiple_choice import Q1

Q1

Notwithstanding the ‘correct’ result, the actual response is that ‘it depends’.

The simulator moves the robot at each iteration of the event loop by noting the motor speed, multiplying the step duration (1/frame_rate) by the speed to work out how far the robot has moved in that step, calculating the new position, and then redrawing the robot at this new location.

Another part of the event loop determines the motor speed.

If the robot has zero mass, the motor speed is set to the requested motor speed. However, if the robot has a mass, a simple acceleration model is employed that sets the new speed difference in proportion to frame_rate/robot_mass: the faster (lower) the frame rate, or the heavier the robot, then the lower the speed difference.

By default, the simulated robot does have a simulated mass, so it does take time to accelerate up to the requested motor speed. A checkbox in the Settings panel of the simulator allows you to configure the robot to weightless and allow a program downloaded to the simulator to instantaneously set the motor speed levels without any acceleration period.

6.3 Summary

Writing programs to control robots can be a challenging task. For example, not only do you have to contend with working out what you want the robot to do, but also how to go about doing it, and how to write the code to provide the control instructions. But you also need to bear in mind that the world the robot is operating in, as well as the physical state of the robot itself, may be subject to a further set of independently applied physics rules in addition to the rules of behaviour your program code defines.

This completes the practical activities for this week.