Developers

Under the hood
of one robot language.

How a line becomes motion, the protocol on the wire, the whole vocabulary, and why the checker, not the AI, has the last word.

← Back to Elara and the live demo
01 · How it works

One instruction, from words to the motor. Every value below is real output from the URITP tools; the robot end is the simulated test endpoint, so the move takes no real time (took=0).

Sourcedrive rover.base forward by 1m speed 0.3m/s
Lexeruritp/lexer.py
NAME driveNAME roverOP .NAME baseNAME forwardNAME byQUANTITY 1 mNAME speedQUANTITY 0.3 m/s
Checkeruritp/checker.py
frame base exists on roverprofile navigation: yes1m is a Length, 0.3m/s is a Speed0.3m/s ≤ safety limit 0.5m/sok: no errors
Compileruritp/compiler.py
DRIVE frame=base direction=forward distance=1 speed=0.3
Wireprotocol 0.4, TCP
host → INSTR id=1 op=DRIVE frame=base direction=forward distance=1 speed=0.3robot → ACK id=1 status=acceptedrobot → RESULT id=1 status=ok took=0

The checker row lists what it verified against the rover's manifest; its printed verdict is the last line.

What the checker stops, before anything moves

  • E304wait needs a Time, got a bare number '10'. Did you mean 10s?
  • E502speed 3m/s exceeds safety limit 1.2m/s for 'Office delivery rover (simulated)'
  • E203robot 'rover' has no frame 'tool' (it has: base)
  • E401'takeoff' requires profile 'flight'; rover supports [core, navigation, speech]

Each message verbatim from uritp check. Nothing is sent to a robot until it passes.

02 · Wire protocol

Teach a robot URITP once. After that, any program drives it, over USB or TCP, with nothing generated for it and nothing uploaded again between programs.

hosturitp wire 0.4 · one line per messagerobot
  1. HELLO proto=0.4 role=host program="office_delivery.uritp" heartbeat_ms=300Handshake
  2. HELLO proto=0.4 role=robot impl=uritp-arduino/0.4 name="Arduino Uno robot car"It says what it is
  3. INSTR id=7 op=DRIVE frame=base direction=forward distance=2 speed=0.5One instruction
  4. ACK id=7 status=acceptedGot it, or refused with a code
  5. RESULT id=7 status=ok took=4.1Done, and how long it took
  6. INSTR id=9 op=SENSE sensor=distance_frontRead a sensor
  7. RESULT id=9 status=ok value=0.420.42 m to the front
  8. STOP id=12 reason="the program asked"Anyone can stop it
  9. EVENT kind=state state=stopped reason="the program asked"Stopped, and says so

Every message is a line of text, or a binary frame carrying the same fields. Amounts are plain numbers in SI units: metres, seconds, m/s.

  • Stops on silence

    If the computer goes quiet for 2 s (a pulled cable, a crash), the robot stops itself, mid-move too.

  • Never twice

    A lost message is asked about, never sent again blindly. No instruction is carried out twice.

  • Checks again

    The robot refuses a part it doesn't have (E203) or a speed over its limit (E502), whatever the computer said.

  • Runs on its own

    Upload a checked program and it keeps running with the computer gone. A STOP still ends it at once.

Binary frames: 64% of the bytes

CBOR in SLIP frames, with a CRC-16 on every one. Measured, in bytes.

  • Robot HELLO218139
  • Host HELLO9460
  • DRIVE7241
  • STOP3525
  • ACK2520
  • RESULT2214

Down to 1 KB of RAM

The URITP library on each board, RAM used, from the boards' own compilers.

  • ATmega168 1 KB RAM54%binary frames only
  • Arduino Uno 2 KB RAM30%text and binary
  • Arduino Mega 8 KB RAM11%with a key
  • ESP32 320 KB RAM6%Wi-Fi, with a key
03 · The language

Plain verbs, real units, one grammar for every robot.

Connect

robot NAME = connect("ADDRESS")
Connect to a robot; its manifest says what it can do.
import "site.uritp"
Bring in a site map of places, zones and routes.
record Bin(spot: Place, max_load: Mass)
Group values under one name, with types.

Move

move ROBOT.FRAME to TARGET [linear|joint] [speed Q]
Send a frame to a place, an object or a pose.
pose(x, y, z, roll=A, pitch=B, yaw=C)
A full 6-DoF pose, measured from the site.
avoid zones.NAME
A zone the path must never cross.
drive · turn · takeoff · land
Drive a base, turn, or fly.

Handle and talk

grip ROBOT.ACTUATOR open|close [force Q]
Open or close a gripper.
pick OBJECT using ROBOT [onto TARGET]
Pick something up.
say "TEXT" [lang CODE] · confirm "QUESTION"
Speak in any language; wait for a yes.

Flow

if · for NAME in LIST · repeat N times:
Choices and loops.
task NAME(ARGS):
Reusable steps, checked again for each robot.
parallel:
Start statements together; one order per part.
wait DURATION · wait until CONDITION
Pause, or wait for something to be true.

When things go wrong

on fail [R802]:
Handle every failure above it, or only the ones it names.
retry N times:
Run a block again if it fails, up to N times.
STATEMENT timeout DURATION
Stop an order that takes too long (R704).
when CONDITION:
React the moment something becomes true, while the program goes on.

Decide

decide NAME from OPTIONS by fastest|safest|learned
Plan every option without moving, then choose.
predict(VALUE, in=DURATION)
Look ahead: a value as it will be later.

Units

Lengthmm cm m km
Angledeg rad
Timems s min h
Speedmm/s cm/s m/s km/h
Massg kg
ForceN

Every amount carries its unit, with no space: 10cm, 0.2m/s, 90deg. A bare number is error E304. On the wire, amounts are plain numbers in SI units (metres, seconds, m/s, radians): distance=1 speed=0.3 is 1 m at 0.3 m/s.

Run-time codes

  • R704wait until timed out: the condition never came true in time.
  • R802a target is inside a closed zone, or can't be reached without entering it.

E-codes stop a program before it runs; R-codes are failures reported while it runs.

04 · AI, checked

Say what you want in any language. An AI writes the program; the checker decides whether it may run.

  1. 1

    Ask

    In any language, typed or spoken.

  2. 2

    The AI writes URITP

    From the robot's manifest and the site map.

  3. 3

    ElaraCheck checks it

    Units, limits, zones, abilities.

  4. 4

    Errors go back

    The AI fixes them, twice at most.

  5. 5

    You approve. It runs.

    It asks you first when a wrong move would cost more than a question.

Within what the checker checks, the AI can never make a robot do anything the checker rejects. Your own model (Ollama, vLLM, llama.cpp, LM Studio), Gemini or Claude.

uritp ask "put it there"Ask, or run?
How sure: a 25% chance this is not what you meant.A wrong move costs about 10 questions, so runningcosts about 2.5: worth asking first.I had to guess (you said "it", "there"). I understood:    move rover.base to places.desk_14Is that what you meant? [y/N]

It weighs the chance it guessed wrong against what a wrong move costs, and asks first when that is worth it.

hurry.uritpuritp check --predict
import "warehouse.uritp"robot cart = connect("play:cart")move cart.base to places.aisle_b speed 1.5m/smove cart.base to places.loading speed 1.4m/smove cart.base to places.dock
ok: no errorsElaraCheck Predict:  (demo figures, learned from simulated practice runs)  chance something goes wrong: 38%  chance of a collision:       27%  time, as planned:            about 16s  decision: WARN  try: at most 0.5m/s on lines 4, 5, 6: then 24% and 1%

ElaraCheck Predict: an allowed program can still be risky. It gives the chance of trouble, learned from past runs (here, simulated practice runs), and a fix to try.