Asset package
An asset is the reusable definition of a piece of hardware: its 3D meshes and kinematic model. Cyberwave creates a custom asset from a URDF package that you upload.What is a URDF?
URDF (Unified Robot Description Format) is the standard XML format used in ROS to describe a robot’s links, joints, visuals, and collisions. Useful open-source references: A complete sample is available: dji-mini-4-pro.zip (onebase_link, four propeller links, four continuous joints).
ZIP layout
The package is a single ZIP archive that contains:- One main
.urdf(or.xacro) file - Every file referenced by that URDF (meshes, textures, materials)
Cyberwave unpacks and validates the archive after you create the asset.
File references inside URDF
Your URDF can reference other files, for example:- STL files for collision geometry
- OBJ files for visual geometry / textured visuals
- Texture image files used by materials (for example PNG/JPG)
Use relative paths that match your ZIP structure. If the URDF references
meshes/arm_visual.obj, that file must exist in the ZIP. ROS package:// URIs must be switched to relative paths.Upload form fields
The dashboard upload has three steps: Package, Details and Access. The steps are in Create the asset.Upload from the API (create-with-urdf)
Use:
POST /api/v1/assets/create-with-urdf
Python SDK upload methods are listed on the Catalog page.
Set physics properties
When Cyberwave processes your URDF ZIP it generates a universal schema — the canonical JSON representation of your robot. The schema includes aphysics object that controls world-level simulation parameters such as gravity, timestep, solver, and default contact surface.
There is no physics editor in the UI yet. Use the PATCH API below to configure physics after uploading.
Physics object structure
Set physics via API
Use the universal schema PATCH endpoint:PATCH /api/v1/assets/{uuid}/universal-schema
Set physics via Python SDK
The Python SDK provides convenience methods so you don’t need to craft JSON Pointer operations manually. All setter methods use a read-modify-write pattern: omitted fields keep their current values.set_physics — set multiple physics fields at once
set_gravity — shorthand for the gravity vector
set_physics_solver — configure the solver
set_contact_properties — tune the default contact surface
get_physics — read the current physics
None if no physics have been configured yet.
Universal schema helpers (Python SDK)
Beyond physics, the SDK exposes general-purpose methods for reading and writing any part of the universal schema.get_universal_schema — download the full schema
get_universal_schema_at_path — read a specific sub-path
patch_universal_schema — write to any JSON Pointer path
rebuild_universal_schema — regenerate from source files
Physics tuning best practices
Getting physics parameters right is the difference between a simulation that behaves like the real world and one that explodes on the first contact. This section distills practical guidance from the MuJoCo, Bullet, and Gazebo communities.Pick the right timestep
The timestep is the single most impactful parameter. Too large and the simulation becomes unstable; too small and you waste compute for no visible gain.Choose a solver type
Cyberwave maps solver types to the underlying engine. Use this as a starting point:
Increase
iterations (default 50) when you see jitter or interpenetration at contacts. Higher iterations improve accuracy at the cost of speed — 100–200 is a reasonable upper bound before you should reduce the timestep instead.
Tune contact parameters for realism
Default contact values are deliberately “grippy” (high friction, low restitution). This works well for tabletop manipulation but may need adjustment for other scenarios. Friction (mu_static, mu_dynamic)
Restitution (bounciness)
0.0– completely inelastic (objects stick on contact) — good for grippers and heavy payloads0.1– default; slight energy absorption0.5 – 0.8– bouncy; use for balls, elastic impacts1.0– perfectly elastic (no energy loss) — rarely realistic
Prepare for sim-to-real transfer
If your goal is to deploy policies trained in simulation onto real hardware, physics parameters are a critical part of the reality gap. 1. Measure, don’t guess. Use a scale, force gauge, or system identification to get real mass, inertia, and joint friction values. Even rough measurements beat defaults — research shows unexpectedly high friction-torque ratios in real joints compared to simulation defaults. 2. Randomize what you can’t measure. Domain randomization over physics parameters helps policies generalize. Randomize friction (±30%), mass (±10%), and contact stiffness across training episodes. This is especially important for contact-rich tasks like assembly or grasping. 3. Validate on simple motions first. Before training a full policy, compare simulated vs. real joint trajectories on a basic motion (e.g., gravity drop, sine-wave tracking). If these diverge, fix the model before scaling up. 4. Iterate on the timestep last. Changing the timestep affects controller gains, contact behavior, and training speed simultaneously. Get other parameters right first, then tune timestep if needed.A policy that achieves 95% success in simulation can drop to 30–50% on real hardware without careful parameter calibration. Investing time in physics tuning pays off more than training longer.
Common pitfalls
Driver config files
Four files come up when you integrate a robot. They do different jobs.The image that runs for your robot is set in the asset’s
metadata.drivers, not in a cyberwave.yml driver: block. The method that registers a driver interface is twin.driver.set_schema(...). twin.commands only invokes and lists commands.cw-driver.yml topic mapping
Each YAML path under mqtt compiles to a flat MQTT topic:
commands.supported entries are either a plain name (discrete, one-shot) or an object such as { name: move_forward, continuous: true, rate_hz: 10 } (stick-held). set_schema compiles the file through POST /api/v1/twins/{uuid}/driver-schema. Full topic list: MQTT reference.
metadata.drivers keys
Edge Core reads metadata.drivers on the asset (or twin) and starts one container per linked twin.
On a Jetson with no Jetson key, Edge Core tries a
jetson--prefixed tag first. Changing the asset affects twins created afterwards. Reference: Drivers.
Driver environment variables
Edge Core injects these when it runs your container, so you can assume they’re always set:
Other variables used by drivers:
Supported protocols
Integration happens at the driver layer, so Cyberwave is protocol-agnostic and sits alongside the tools your team already uses. The same driver pattern bridges any of these to the digital twin:- ROS 1 / ROS 2: robot arms, mobile robots, and sensor stacks
- VDA5050: AGV / AMR fleet communication
- OPC UA: industrial automation and PLC connectivity
- Modbus TCP / RTU: sensor and actuator networks
- gRPC / REST: custom services and microservice architectures
- Serial / USB: direct device control (servos, microcontrollers)