OSPL is a deterministic, URScript-compatible scripting language that compiles scripts into a shared object (.so) and executes them as plugins inside a long-running container process.
This repository contains:
libs/osplrt– runtime library (VM + standard library + host API bridge)apps/osplc– compiler CLI: parses URScript/OSPL and emits a plugin.soapps/ospld– container/daemon CLI: loads/unloads plugins and starts/stops scripts at runtimetools/osplc_py– Python frontend that generates plugin C++examples/– example scripts
Across dlopen() boundaries you want a stable ABI. C++ name mangling and STL types are compiler/libstdc++-version sensitive.
Therefore the plugin ABI is C (extern "C") and uses opaque pointers and plain structs.
Internally everything is C++20.
You can export additional C++ symbols if you control both sides with the same compiler + standard library, but it is not recommended for long-lived plugins.
- URScript-like syntax:
def/end, indentation-based blocks,if/elif/else,while,break/continue,return,halt - Types:
None,bool,number(int/float),string,list,pose(p[x,y,z,ax,ay,az]) - Operators: arithmetic, comparisons, boolean ops
and/or/xor/not - Indexing:
a[i],m[i,j], and index assignment - Threads:
thread,run,join,kill,enter_critical/exit_critical - Deterministic execution model (no JIT, no randomness)
- Cooperative termination: container can request stop; VM checks a cancellation flag at statement boundaries and in time-consuming builtins like
sleep(). - Runtime compilation + loading/unloading via
ospldCLI - Code quality:
clang-format,clang-tidy,cppcheckintegration in CMake
- Linux (tested on Ubuntu 22.04/24.04)
cmake>= 3.20clang++org++(C++20)python3- optional:
clang-tidy,clang-format,cppcheck
cmake --preset default
cmake --build --preset defaultManual fallback:
cmake -S . -B build -G Ninja -DCMAKE_BUILD_TYPE=RelWithDebInfo
cmake --build build --parallelThis produces:
build/bin/ospld(container)build/bin/osplc(compiler wrapper)build/lib/libosplrt.so(runtime)
./build/bin/osplc examples/hello.ospl -o /tmp/hello.so./build/bin/ospld
ospld> load /tmp/hello.so hello
ospld> start hello main
ospld> stop hello
ospld> unload hello
ospld> quitOSPL separates script semantics from robot control side-effects.
- The runtime provides a set of builtin function names (e.g.
movej,movel,speedj, IO functions, etc.) as described in the URScript manual. - The container may supply a
HostApivtable that implements these functions. - If a function is not provided by the host:
- math/string/list builtins are implemented in
osplrt - robot-specific functions default to host-only and are forwarded to the container. The sample container (
ospld) includes a deterministic mock robot service for a few common calls (e.g.movej,movel,get_actual_joint_positions,get_actual_tcp_pose).
- math/string/list builtins are implemented in
haltterminates the current script.ospld stop <name>requests termination.- The runtime uses cooperative cancellation: it is deterministic and safe, but requires the script to occasionally execute VM instruction boundaries or time-consuming builtins.
- A thread stuck in an infinite tight loop without
sleep()/sync()can still be terminated because the VM checks the cancel flag at each executed instruction.
Builtins are defined in libs/osplrt/src/builtins_registry.cpp. If a builtin name is not registered, but a host is present, the VM forwards it to the host (URScript compatibility mode).
- To implement a builtin in runtime: register
BuiltinFn. - To forward to host: mark it as
HostOnly.
cmake --build --preset default --target format
cmake --build --preset default --target format-check
cmake --build --preset default --target tidy
cmake --build --preset default --target cppcheckGitHub Actions (.github/workflows/ci.yml) runs:
lint— clang-format check, cppcheck, clang-tidy (advisory)build_smoke— build + compiler/daemon smoke checkscoverage— gcovr report artifactspackaging— CPack.tar.gzpackage artifact
This project aims to be URScript-compatible at the syntax/function level, while keeping execution deterministic.
- Programs are functions beginning with
defand ending withend. - Poses use
p[...]. - Flow control uses
if/elif/else/endandwhile/end. - Robot/motion builtins (e.g.
movej/movel) are forwarded to the container host.
MIT (repository code). URScript/UR documentation is not redistributed.