Why Neuracore / ROS-independent

Use it with ROS. Use it without. Your call.

Neuracore is a plain Python SDK, not a middleware. You can run collection, training, and deployment end to end with no ROS anywhere in the stack, and multi-node setups work out of the box. If you already run ROS, nothing changes: wherever you publish a topic, you can also log to Neuracore.

Engineer working at a Neuracore workstation with an AgileX robot arm and live data dashboards
Two paths, one API

The same nc.log_* calls, ROS or not.

The whole SDK is a handful of top-level functions: connect a robot, start a recording, log any of 14 modalities, stop. Those calls don't care where the data comes from, a control loop, a simulator, or a ROS callback.

No ROSA plain Python loop
collect.py
import neuracore as nc
nc.login()
nc.connect_robot("arm-01", urdf_path="arm.urdf")
nc.create_dataset("pick-place")
nc.start_recording()
while collecting:
    t = time.time()
    nc.log_joint_positions(joints, timestamp=t)
    nc.log_rgb("wrist_cam", frame, timestamp=t)
nc.stop_recording()  # auto-uploads

No graph, no nodes, no launch files. Anything that can hand you an array can feed Neuracore.

Already on ROSLog from your callbacks
ros_node.py
import neuracore as nc
nc.login()
nc.connect_robot("arm-01", urdf_path="arm.urdf")
nc.start_recording()
# wherever you already publish,
# also log to Neuracore
def on_joint_state(msg):
    t = stamp_to_sec(msg.header.stamp)
    nc.log_joint_positions(as_dict(msg), timestamp=t)
def on_image(msg):
    t = stamp_to_sec(msg.header.stamp)
    nc.log_rgb("wrist_cam", to_ndarray(msg), timestamp=t)

Subscribe to the topics you already run, add one nc.log_* line, and the same stream is now recorded, synchronized, and ready to train.

Distributed by default

Multi-node, out of the box.

Cameras on one machine, arms on another? Log from each, and Neuracore fuses them over WebRTC into a single, timestamped observation. No ROS network, no DDS tuning, no shared clock to configure.

  • Fused into one SynchronizedPoint over WebRTC, the same structure used at training and inference.
  • Every log call carries its own timestamp, so heterogeneous sensors align to an exact capture time.
  • Loops gate on all expected nodes being connected before they run.
multi_node.py
# gate on every streaming node
nc.check_remote_nodes_connected(
    "arm-01", n=2)
# one fused, synchronized point
point = nc.get_latest_sync_point(
    "arm-01",
    include_remote=True)
# cameras + arms, already aligned
action = policy.predict(timeout=5)
Deploy anywhere

One policy, three ways to run it.

The same trained policy runs however your stack is wired, in your Python process, on a local server next to the robot, or on a managed cloud endpoint. Wrap it in a ROS node if you want; it works exactly the same if you don't.

Direct

In-process

Zero-network inference inside your own Python process. The lowest-latency path, no server to stand up.

Local

Local server

Run the policy on a machine right next to the robot, on your network, off the public internet.

Cloud

Managed endpoint

A GPU-backed cloud endpoint Neuracore operates. Hot-swap checkpoints without a restart.

What we don't do
  • No middleware to adopt, no message graph to model your system around.
  • No requirement to rewrite existing ROS nodes or launch files.
  • No lock-in: data is yours, exportable, and the core library is open source.
What you get
  • A one-line logging API for 14 modalities from any source.
  • Cross-machine data fusion and multi-instance, bimanual fleets, handled for you.
  • One flow from collection to training to real-time deployment.
Get Started

Bring whatever stack you already have.

ROS 2, a bare control loop, or a simulator, the same few lines get you from robot to recorded data to a deployed policy.

See the SDK