OPAL Commands

Built-in commands and functions reference

OPAL Commands

Complete reference for all built-in commands and functions available in OPAL (OctoMY™ Programming and Automation Language).

Pro Tip

Always include a delay() in your loop blocks - even just delay(50) for 20Hz updates. Without a delay, your plan will consume 100% CPU and may trigger the E207 timeout error. The delay also gives other plans and system tasks a chance to run.


Control flow

delay

Pause execution for a specified time.

delay(milliseconds)
Parameter Type Description
milliseconds number Time to pause in ms
delay(100)    // 100ms pause
delay(1000)   // 1 second pause

wait_for

Wait for a condition to become true.

wait_for(condition)
wait_for(condition, timeout_ms)
Parameter Type Description
condition expression Condition to wait for
timeout_ms number Maximum wait time (optional)
wait_for(sensors.distance.front < 30)
wait_for(battery.level > 20, 5000)  // 5s timeout

if / else

Conditional execution.

if condition {
    // code
} else if other_condition {
    // code
} else {
    // code
}
if distance < 30 {
    stop()
} else if distance < 60 {
    slow_down()
} else {
    full_speed()
}

loop

Continuous execution loop.

loop {
    // code runs forever
}
loop {
    check_sensors()
    update_motors()
    delay(50)
}

for

Iterate over a range or collection.

for i in start..end {
    // code
}

for item in collection {
    // code
}
// Count 0 to 9
for i in 0..10 {
    log("Count: " + i)
}

// Iterate array
var readings = [10, 20, 30]
for r in readings {
    log("Reading: " + r)
}

while

Loop while condition is true.

while condition {
    // code
}
var count = 0
while count < 10 {
    log("Count: " + count)
    count = count + 1
}

break

Exit the current loop.

loop {
    if should_stop {
        break
    }
}

continue

Skip to next loop iteration.

for i in 0..10 {
    if i == 5 {
        continue  // Skip 5
    }
    log(i)
}

Motor control

drive

Set both motor speeds for differential drive.

drive(left_speed, right_speed)
Parameter Type Range Description
left_speed number -100 to 100 Left motor speed
right_speed number -100 to 100 Right motor speed
drive(60, 60)    // Forward
drive(-60, -60)  // Reverse
drive(50, -50)   // Spin right
drive(-50, 50)   // Spin left
drive(60, 30)    // Curve right

stop

Stop all motors immediately.

stop()

set_motor

Set individual motor speed.

set_motor(name, speed)
Parameter Type Description
name string Motor identifier
speed number Speed -100 to 100
set_motor("motors.left", 50)
set_motor("motors.right", 50)

set_servo

Set servo position.

set_servo(name, angle)
set_servo(name, angle, speed)
Parameter Type Description
name string Servo identifier
angle number Target angle in degrees
speed number Movement speed (optional)
set_servo("head.pan", 90)          // Center
set_servo("head.tilt", 45)         // Look up
set_servo("arm.shoulder", 120, 50) // Move slowly

Sensor access

sensors

Access sensor readings.

sensors.<category>.<name>
Path Type Description
sensors.distance.front number Front distance (cm)
sensors.distance.left number Left distance (cm)
sensors.distance.right number Right distance (cm)
sensors.imu.heading number Compass heading (degrees)
sensors.imu.pitch number Pitch angle (degrees)
sensors.imu.roll number Roll angle (degrees)
sensors.imu.accel.x number X acceleration (g)
sensors.imu.accel.y number Y acceleration (g)
sensors.imu.accel.z number Z acceleration (g)
sensors.line.left boolean Left line detected
sensors.line.center boolean Center line detected
sensors.line.right boolean Right line detected
sensors.bump.front boolean Front bumper triggered
sensors.light number Ambient light (0-100)
sensors.temperature number Temperature (Celsius)
var dist = sensors.distance.front
var heading = sensors.imu.heading
var on_line = sensors.line.center

battery

Access battery status.

battery.level      // Percentage 0-100
battery.voltage    // Voltage in V
battery.charging   // Boolean
battery.low        // Boolean (< 20%)
if battery.level < 20 {
    return_to_base()
}

Logging

log

Output a message to the log.

log(message)
log("Starting patrol")
log("Distance: " + sensors.distance.front + " cm")

log_debug

Debug-level logging (verbose).

log_debug(message)

log_warn

Warning-level logging.

log_warn(message)

log_error

Error-level logging.

log_error(message)
log_debug("Checking sensor...")
log("Sensor value: " + value)
log_warn("Battery low!")
log_error("Sensor not responding!")

Math functions

abs

Absolute value.

abs(-5)  // Returns 5

min / max

Minimum and maximum.

min(a, b)    // Smaller value
max(a, b)    // Larger value
min(5, 10)   // 5
max(5, 10)   // 10

clamp

Constrain value to range.

clamp(value, min, max)
clamp(150, 0, 100)  // Returns 100
clamp(-20, 0, 100)  // Returns 0
clamp(50, 0, 100)   // Returns 50

round / floor / ceil

Rounding functions.

round(3.7)  // 4
floor(3.7)  // 3
ceil(3.2)   // 4

sqrt / pow

Square root and power.

sqrt(16)      // 4
pow(2, 3)     // 8
pow(10, 2)    // 100

sin / cos / tan

Trigonometric functions (radians).

sin(0)       // 0
cos(0)       // 1
sin(3.14159/2)  // ~1

atan2

Two-argument arctangent.

atan2(y, x)  // Angle in radians

degrees / radians

Angle conversion.

degrees(3.14159)  // ~180
radians(180)      // ~3.14159

random

Generate random number.

random()           // 0.0 to 1.0
random(max)        // 0 to max
random(min, max)   // min to max
var r = random(100)        // 0-100
var angle = random(-45, 45) // -45 to 45

String functions

length

String length.

length("hello")  // 5

substring

Extract substring.

substring(str, start)
substring(str, start, length)
substring("hello", 1)      // "ello"
substring("hello", 1, 3)   // "ell"

contains

Check if string contains substring.

contains("hello world", "world")  // true

starts_with / ends_with

Check string prefix/suffix.

starts_with("hello", "he")  // true
ends_with("hello", "lo")    // true

split

Split string into array.

split("a,b,c", ",")  // ["a", "b", "c"]

join

Join array into string.

join(["a", "b", "c"], "-")  // "a-b-c"

to_string

Convert value to string.

to_string(42)     // "42"
to_string(3.14)   // "3.14"
to_string(true)   // "true"

to_number

Parse string to number.

to_number("42")    // 42
to_number("3.14")  // 3.14

Array functions

length

Array length.

var arr = [1, 2, 3]
length(arr)  // 3

push

Add element to end.

var arr = [1, 2]
push(arr, 3)  // arr is now [1, 2, 3]

pop

Remove and return last element.

var arr = [1, 2, 3]
var last = pop(arr)  // last is 3, arr is [1, 2]

shift / unshift

Add/remove from beginning.

var arr = [2, 3]
unshift(arr, 1)      // arr is [1, 2, 3]
var first = shift(arr)  // first is 1, arr is [2, 3]

slice

Extract portion of array.

var arr = [1, 2, 3, 4, 5]
slice(arr, 1, 3)  // [2, 3]

find

Find first matching element.

var arr = [1, 2, 3, 4, 5]
find(arr, x -> x > 3)  // 4

filter

Filter elements by condition.

var arr = [1, 2, 3, 4, 5]
filter(arr, x -> x > 2)  // [3, 4, 5]

map

Transform elements.

var arr = [1, 2, 3]
map(arr, x -> x * 2)  // [2, 4, 6]

reduce

Reduce array to single value.

var arr = [1, 2, 3, 4]
reduce(arr, (acc, x) -> acc + x, 0)  // 10

Communication

broadcast

Send message to all peers.

broadcast(event_name, data)
broadcast("status_update", {state: "moving"})
broadcast("obstacle_detected", {x: 10, y: 20})

send_to

Send message to specific peer.

send_to(peer_name, event_name, data)
send_to("Worker Beta", "task", {id: 123})

on_message

Handle incoming messages.

on_message(event_name) { data ->
    // handle data
}
on_message("task") { task ->
    log("Received task: " + task.id)
    execute_task(task)
}

Time

now

Current timestamp in milliseconds.

var timestamp = now()

time

Current time components.

time.hour      // 0-23
time.minute    // 0-59
time.second    // 0-59
time.day       // 1-31
time.month     // 1-12
time.year      // e.g., 2024
time.weekday   // 0-6 (Sunday=0)
if time.hour >= 22 || time.hour < 6 {
    log("Night mode")
}

elapsed

Time since a reference point.

var start = now()
do_something()
var duration = now() - start
log("Took " + duration + "ms")

State management

var

Declare a variable.

var name = value
var speed = 60
var state = "idle"
var readings = []
var config = {threshold: 30, speed: 50}

const

Declare a constant.

const MAX_SPEED = 100
const PI = 3.14159

global

Access global state.

global.key = value
var x = global.key
global.patrol_count = 0

plan Patrol {
    loop {
        patrol_area()
        global.patrol_count = global.patrol_count + 1
    }
}

Functions

function

Define a function.

function name(params) {
    // code
    return value
}
function calculate_distance(x1, y1, x2, y2) {
    var dx = x2 - x1
    var dy = y2 - y1
    return sqrt(dx*dx + dy*dy)
}

var dist = calculate_distance(0, 0, 3, 4)  // 5

return

Return value from function.

function is_close(distance) {
    return distance < 30
}

Error handling

try / catch

Handle errors gracefully.

try {
    risky_operation()
} catch error {
    log_error("Failed: " + error.message)
}

throw

Raise an error.

if battery.level < 5 {
    throw "Battery critically low"
}

Navigation

navigate_to

Move to a position.

navigate_to(x, y)
navigate_to(x, y, heading)
navigate_to(100, 200)
navigate_to(0, 0, 0)  // Return to origin facing north

turn_to

Turn to face a heading.

turn_to(heading)
turn_to(90)   // Face east
turn_to(180)  // Face south

position

Current position.

position.x
position.y
position.heading
log("At: " + position.x + ", " + position.y)

Plan control

activate

Activate another plan.

activate(plan_name)
if emergency {
    activate("EmergencyStop")
}

deactivate

Stop a running plan.

deactivate(plan_name)
deactivate()  // Stop current plan

pause / resume

Pause and resume plans.

pause("PatrolPlan")
// ... do something ...
resume("PatrolPlan")

In this section
Topics
reference OPAL commands functions programming
See also