Movements

Movements control the robot's motors and control system. You can use sequential movement commands by separating them with line breaks, like the Hello World! program. Sphero robots move with three basic instructions: heading, speed, and duration. For example, if you set heading = 0°, speed = 60, duration = 3s, the robot would roll forward for 3s at a moderate speed. Some robots, like Sphero BOLT+ and Sphero RVR/RVR+ have improved motor encoders, which means you can set your robot to roll for a specific distance in centimeters (cm) rather than for a period of time.

What is the 255 scale, and why is it used for speed?

The scale relates to computer memory and it's used instead of a percentage to allow young users to gain familiarity with how computer memory works. Memory at its most basic form consists of the binary digits 0 and 1 where a single one of those digits is referred to as a bit. Though a single bit can only represent 0 or 1, multiple bits can be combined to represent larger values, just as the single digits 1, 2, and 3 can be combined to represent the number 123 in the base 10 decimal counting system we typically use outside of the context of programming. In that base 10 example,  the 3 in the ones place, the 2 in the tens place, and the 1 in the hundreds place combine to represent the number one-hundred  twenty-three.  Since a binary digit can only represent one of two values, counting in binary uses a ones place, a twos place, a fours place, an eights place, a sixteens place, etc. instead of ones, tens, hundreds, places. 

Analyzing how a computer counts to five illustrates this concept. A 0 in the ones place (0) equals zero. A 1 in the ones place (1) equals one. A 1 in the twos place and a zero in the ones place (10) equals two. A 1 in both the ones and twos places (11) add together to equal three. A 1 in the fours place (100) equals four. Lastly, a 1 in both the fours and ones places (101) equals five. To recap, a computer counting from zero to five looks like 0, 1, 10, 11, 100, 101. Whereas a bit represents a single 1 or 0, a byte represents eight bits. Since a byte can thus contain eight ones or zeroes, the largest value a byte can represent with all eight bits filled with ones (11111111) equals 255. Therefore, using the smallest amount of memory for a value (one byte) offers a range of 0 - 255. Since Sphero robots have limited memory for storing values it's important to be efficient with our memory usage hence we use a single byte with the possible values from 0 - 255 to represent speed.

Roll

await roll() combines heading (0 - 360°), speed (-255 - 255), and duration(time (s)) to make the robot roll with one line of code. For example, to have the robot roll at 90°, at speed 200 for 2s, use await roll(90, 200, 2).

Roll to Distance

await rollToDistance() combines heading (0 to 360°), maximum speed (-255 to 255), and distance (in centimeters) to make BOLT+ and RVR/RVR+ roll with one line of code. For example, if you want to roll at 90°, at a maximum speed of 200 for 200cm, then use await rollToDistance(90, 200, 200). Consider that distance accuracy is dependent on multiple factors, including the surface under your BOLT+ or RVR/RVR+ and the weight of any payload on board (in the case of RVR/RVR+).

Since BOLT+ and RVR/RVR+ are trying to accurately target a precise distance with Roll to Distance, the firmware control systems will manage speed differently than when using await roll(). There is a period of acceleration and deceleration at the start and end of the robot movement. This acceleration ramping helps reduce the slippage that would impact encoder accuracy. As a result, your maximum speed setting may not be met if you have set your BOLT+ or RVR/RVR+ to roll a shorter distance. Experiment with your set distance and maximum speed to get the results you need.

Drive

drive() enables or disables a driving interface in the Sphero Edu application. This allows you to manually drive your Sphero BOLT+ while executing additional code. To enable the driving interface, use drive(true).  To disable the driving interface, use drive(false)

It's important to understand that the driving interface will be disabled automatically if most of the movement commands are used after the drive command. For example, observe the following code snippet: 

drive(true);
await delay(25);
await roll(0, 255, 5);

In this example the driving interface will appear and be available for use for 25 seconds, which is the duration of the set delay. Once the roll command occurs the driving interface will automatically be disabled. The following movement commands will disable the driving interface when used after the Drive command: 

The following movement commands will not disable the driving interface when used after the Drive command

The driving interface has two UI elements; controls to drive your BOLT+ and a speed slider. Since there is no aim control in the driving interface, you will need to use the Reset Aim command in creative ways to reset your heading. For example, you can reset aim immediately after the drive command: 

drive(true);
resetAim();

Alternatively, you could use an On Button event command to manually reset aim with a simple press of the software button at any time: 

var _softwareButtonEvents = ['Reset Aim'];


async function startProgram() {

registerSoftwareButton(_softwareButtonEvents);


drive(true);

}


async function onSoftwareButton(button) {

if (button !== 'Reset Aim') return;


resetAim();

}

registerEvent(EventType.onSoftwareButton, onSoftwareButton);

There are many other ways you can creatively aim while using the Drive command. Experiment and explore per your programming needs! 

Stabilization

setStabilization(true) turns the stabilization system on and setStabilization(false) turns it off.  When stabilization is "on" the robot is upright using the Inertial Measurement Unit (IMU), which is a combination of readings from the Accelerometer (directional acceleration), Gyroscope (rotation speed), and Encoders (location and distance).

After calling setStabilization(false) and then powering the motors, the robot will not balance. This will result in unstable behaviors like wobbly driving or jumping if you set the power very high. Some use cases to turn it off are:
1. Jumping: Set Raw Motor to max values and the robot will jump off the ground!
2. Gyro: Programs like the Spinning Top where you want to to isolate the Gyroscope readings rather than having the robot auto balance inside the shell.

When stabilization is off you can't use setSpeed to set a speed because it requires the control system to be on to function. However, you can control the motors using Raw Motor with await rawMotor().

Spin

await spin() spins the robot for a given number of degrees over time, with 360° being a single revolution. For example, to spin the robot 360° over 1s, use: await spin(360, 1). Use setSpeed() prior to await spin() to have the robot move in circle or an arc or circle.

Speed

setSpeed() sets the speed of the robot from -255 to 255, where positive speed is forward, negative speed is backward, and 0 is stopped. Each robot type translates this value differently into a real world speed; Ollie is almost three times faster than Sphero. For example, use setSpeed(188) to set the speed to 188 which persists until you set a different speed. You can also read the real-time velocity value in centimeters per second reported by the motor encoders.

Stop

stopRoll() sets the speed to zero to stop the robot, effectively the same as the setSpeed(0) command.

Heading

setHeading() sets the direction the robot rolls. Assuming you aim the robot with the blue tail light facing you, then 0° is forward, 90° is right, 270° is left, and 180° is backward. For example, use setHeading(90) to face right.

Raw Motor

await rawMotor() controls the electrical power sent to the left and right motors independently, on a scale from -255 to 255 where positive is forward, negative is backward, and 0 is stopped. If you set both motors to full power the robot will jump because stabilization (use of the IMU to keep the robot upright) is disabled when using this command. This is different from setSpeed because await rawMotor() sends an "Electromotive force" to the motors, whereas setSpeed is a target speed measured by the encoders. For example, to set the raw motors to full power for 4s, making the robot jump off the ground, use await rawMotor(255, 255, 4).

Reset Aim

resetAim() resets the heading calibration (aim) angle to use the current direction of the robot as 0°, within a range of 0-360°. For example, use resetAim(90) to use the current right facing direction of the robot as 0°. When used in the block canvas, resetAim() is limited to set the current front facing direction of the robot as 0°.

Sphero BOLT Movements

Sphero BOLT has a compass (magnetometer) sensor that has unique functionality. Nearby metallic and magnetic objects can affect the accuracy of the compass, so try to use this feature in an area without that interference, or hold it up in the air if you can't get away from interference.

Calibrate Compass

await calibrateCompass() calibrates the magnetometer by spinning the robot in place. You need to run this command before setting or getting the compass direction. Nearby metallic and magnetic objects can affect the accuracy of the compass.

Compass Direction

setCompassDirection() sets the real-world direction based on the last compass calibration. 0° is due north, 90° is due east, 180° is due south, and 270° is due west. Requires the Calibrate Compass command to be run before you can set this value.

For example, use the below to point Sphero BOLT to the north:

async function startProgram() {

await calibrateCompass();

setCompassDirection(0);

}

Star Wars Droid Movements

Droid Animations

await Animation.DroidName.Category.AnimationName.play() plays iconic Star Wars Droid animations unique to BB-8, BB-9E, and R2-D2 that combine movement, lights and sound. The droid names are written as BB8, BB9E, and R2D2. You can randomize animations and sounds by not declaring a Category and AnimationName, such as await Animation.R2D2.play(). If you declare a Category but leave the AnimationName blank it will randomize in the given category, such as await Animation.R2D2.Patrol.play(). All animations are listed below:

BB-8

Positive: Giddy, Yes
Negative: Angry, No
Action: Electrified, Number 8, Searching, Square

BB-9E

Action: Retreat, Scan Sweep
Positive: Affirmative, Content, Greetings, Understood, Yes
Negative: Agitated, Alarm, Angry, Antagonized, Furious, No
Watch With Me: Angry, Antagonized, Bored, Bow, Defiant, Disagree, Disappointed, Disbelief, Double Take, Doubtful, Excited, Frustrated, Furious, Happy, Laugh, No, Ominous, Relieved, Shake, Surprised, Uncertain, Yelling, Yoohoo

R2-D2

Action: Drive, Scan, Sleep, Spin
Idle: Idle 1, Idle 2, Idle 3
Negative: Alarm, Angry, Annoyed, Ion Blast, No, Sad, Scared
Patrol: Alarm, Hit, Patrolling
Positive: Chatty, Confident, Excited, Happy, Laugh, Surprised, Yes
Watch With Me: Angry, Anxious, Bow, Concern, Curious, Double Take, Excited, Fiery, Frustrated, Happy, Jittery, Laugh, Long Shake, No, Ominous, Relieved, Sad, Scared, Shake, Surprised, Taunting, Whisper, Yelling, Yoohoo

R2-Q5

Animations are not available for R2-Q5 :(

R2D2.setDomePosition() rotates the dome on its axis, from -160° to 180°. For example, set to 45° using setDomePosition(45).

Stance

Boolean that changes the stance between bipod and tripod. Set to bipod using await setStance(Stance.Bipod) and to tripod using await setStance(Stance.Tripod). Tripod is required for rolling.

Waddle

Boolean that turns the waddle walk on using await setWaddle(true) and off using await setWaddle(false).