Declare a NOVA program with Python
The @nova.program decorator is the foundation of creating robot programs in Wandelbots NOVA.
It transforms your Python function into a NOVA-managed robot program, exposing it through the API and making it discoverable by applications to run them.
After writing and decorating your program, you must register it through NOVAx to make it available in the Program Operator and other Wandelbots NOVA applications. More information on registration is provided at the end of this document.
For detailed and in-depth descriptions on how to write a program with the Python SDK, see the Wandelbots NOVA Python SDK documentation .
Decorator functionality
The @nova.program decorator serves as a developer’s manifest.
It provides program metadata, the controller configuration, validation rules, and optional visualization settings.
Bare
import nova
@nova.program
async def simple_program():
print("Hello World!")The program ID defaults to the function name (simple_program).
with parameters (recommended)
@nova.program(
id="my_robot_program",
name="My Robot Program",
description="A program that performs pick and place operations"
)
async def main():
print("Hello from My Robot Program!")Parameters
id (str, optional)
Unique identifier for the program across your NOVA instance. Must not contain spaces or special characters.
If not provided, the function name is used as the ID.
@nova.program(id="pick_and_place_v2")name (str, optional)
Human-readable display name shown in the Program Operator interface and other NOVA applications.
@nova.program(
id="pick_place",
name="Pick and Place Operation"
)description (str, optional)
Detailed description of what the program does, helpful for documentation and operator guidance.
@nova.program(
id="palletizing",
name="Palletizing Application",
description="Stacks boxes in a 4x4 pattern on EUR pallets with configurable layer height"
)preconditions (ProgramPreconditions, optional)
Defines required robot controllers and their configurations. The Program Operator validates these preconditions before allowing program execution.
from wandelbots.novax import ProgramPreconditions, virtual_controller
import wandelbots.api as api
@nova.program(
id="ur_welding",
name="UR Welding Program",
preconditions=ProgramPreconditions(
controllers=[
virtual_controller(
name="ur10e",
manufacturer=api.models.Manufacturer.UNIVERSALROBOTS,
type=api.models.VirtualControllerTypes.UNIVERSALROBOTS_MINUS_UR10E,
)
],
),
)
async def welding_program():
# Your program logic
passThe preconditions ensure that:
- Required controllers are present in the cell
- Only specified devices are opened and monitored
- Safety features like emergency stop handling are properly configured
The controller name in preconditions must match the robot name configured in the Setup application or via the API exactly.
viewer (Viewer, optional)
Enables program visualization. The most common viewer is nova.viewers.Rerun(), which provides 3D visualization of robot motion.
When enabled, the visualization might impact the cycle time.
3D visualization
@nova.program(
id="motion_test",
viewer=nova.viewers.Rerun()
)
async def test_motion():
# Any plan or execute calls are automatically logged to Rerun
passAdvanced with detailed analysis
@nova.program(
id="complex_motion",
viewer=nova.viewers.Rerun(
show_details=True, # Show detailed analysis panels
show_safety_zones=True, # Visualize safety zones
show_collision_link_chain=True, # Show collision checking
show_collision_tool=True, # Display tool collision geometry
show_safety_link_chain=True, # Show safety link chain
tcp_tools={
"vacuum": "assets/vacuum_cup.stl",
"gripper": "assets/parallel_gripper.stl"
}
)
)The Rerun viewer captures and visualizes robot trajectories and motion paths, TCP poses and transformations, motion group states, planning requests and responses, collision scenes and safety zones, tool geometries attached to specific TCPs.
Learn more about visualization in the Rerun documentation.
Omniverse viewer
@nova.program decorator accepts a viewer protocol specified here .
You can implement your own viewer by implementing this protocol, e.g., an Omniverse viewer.
Configurable function parameters
To make function parameters available to operators, make them available in the Program Operator by exposing variables in your program code. Use type hints and default values for better UI generation.
- Add parameters to your program function.
- Re-run the registration script to update the Program Operator with the new parameter.
- Access the
Parameterstab in the Program Operator UI.
@nova.program(
id="example_program",
name="Example Robot Program",
# ... other configuration
)
async def start(tcp_velocity_limit: int):
# Use the parameter in your robot movements
speed: MotionSettings = MotionSettings(tcp_velocity_limit=tcp_velocity_limit)The Program Operator generates appropriate UI controls based on your parameter types using JSONForms .
Numeric inputs with constraints
Renders as number input fields with minimum and maximum validation.
The ge (greater than or equal) and le (less than or equal) constraints ensure safe operating ranges.
from pydantic import Field
async def program(
speed: int = Field(default=1000, ge=100, le=5000),
precision: float = Field(default=0.5, ge=0.1, le=2.0)
):
passBoolean toggles
Renders as a checkbox or toggle switch.
async def program(enable_safety_check: bool = True):
passString inputs
Renders as a text input field.
async def program(operation_mode: str = "standard"):
passEnums
Renders as a dropdown selection menu.
from enum import Enum
class Material(str, Enum):
STEEL = "steel"
ALUMINUM = "aluminum"
PLASTIC = "plastic"
async def program(material: Material = Material.STEEL):
passRequired
Parameters without default values are marked as required. A value must be provided before starting the program.
Use this to force operators to input critical configuration values.
async def program(
workpiece_id: str, # Required - no default value
cycle_count: int = 100 # Optional - has default value
):
passNext steps
You’re ready to run the program. This includes registering it with NOVAx and executing it from the Program Operator.