robot_msgs
A cohesive domain model for robot data: the standard message types — ROS's geometry_msgs,
sensor_msgs, trajectory_msgs, vision_msgs — as frozen Python dataclasses, with the
functions that move between them. Offsetting a pose, interpolating a trajectory, projecting a
point, turning a depth image into a cloud: first-class methods, not separate libraries.
- ROS's shape, not ROS. Same packages and field names (the ROS docs are our docs), no ROS
install, no codegen. ROS 2 messages and bags are an export (
robot_msgs.ros). - Immutable values over compact numpy storage. Every message is frozen; its arrays are read-only, so slices, rows and columns are free views.
- One runtime dependency: numpy. Plots (
[viz]) and ROS export ([ros]) are extras.
A trajectory is one entity with many views
import numpy as np
from robot_msgs.geometry import Pose
from robot_msgs.trajectory import JointTrajectory
t = np.linspace(0.0, 2.0, 201)
traj = JointTrajectory(
t=t,
joint_names=("shoulder", "elbow"),
positions=np.stack([np.sin(t), np.cos(t)], axis=1),
).with_derivatives()
print(traj) # a summary, never 400 numbers
print(traj.positions.shape) # batch view, no copy
print(traj[100]) # one point
print(traj.at(0.123).positions) # interpolated at any time
for point in traj[:2]: # slices are views too
print(point.t, point.positions)
print(traj.joint("elbow").joint_names) # one joint, still a JointTrajectory
print(traj.resample(dt=0.5).t) # onto a fixed grid
grasp = Pose.from_xyz_rpy(0.5, 0.0, 0.2, np.pi, 0.0, 0.0) # tool pointing down
pregrasp = grasp.shifted(dz=-0.10, local=True) # back off along the tool
print(pregrasp.position)
JointTrajectory(N=201, t=[0 … 2] s, joint_names=('shoulder', 'elbow'), positions=float64[201×2], velocities=float64[201×2], accelerations=float64[201×2])
(201, 2)
JointTrajectoryPoint(t=1.0, positions=[0.8415, 0.5403], velocities=[ 0.5403, -0.8415], accelerations=[-0.8414, -0.5403])
[0.12268879 0.99243461]
0.0 [0. 1.]
0.01 [0.00999983 0.99995 ]
('elbow',)
[0. 0.5 1. 1.5 2. ]
Point(x=0.5, y=1.2246467991473533e-17, z=0.30000000000000004)
JointTrajectory and PoseTrajectory subclass the domain-free Trajectory (samples at strictly
increasing times). Anything else you want to send along rides as channels
(traj.with_channel("kp", kp)); a new kind of trajectory subclasses Trajectory and declares
its sample() fields — it gets indexing, interpolation, plotting and serialisation for free.
Context ROS has no field for (an origin, units, provenance) rides Header.meta, a frozen
str → str mapping that survives every view and file and is dropped on ROS export. A recording
whose stamps repeat or step back is built with
JointTrajectory.from_samples(..., duplicate_times="drop_later" | "average" | "error"), which
returns (trajectory, repair) and writes the same receipt into header.meta; never silently.
Packages
| Import | Types |
|---|---|
robot_msgs.std |
Header |
robot_msgs.geometry |
Vector3 Point Quaternion Pose Pose2D Transform Twist Wrench Accel Inertia PoseStamped TransformStamped · batch maths in geometry.rotations (incl. direct euler_to_matrix / matrix_to_euler) |
robot_msgs.sensor |
JointState Image CameraInfo PointCloud Imu |
robot_msgs.vision |
BoundingBox2D BoundingBox3D ObjectHypothesis ObjectHypothesisWithPose Detection2D Detection2DArray Detection3D Detection3DArray |
robot_msgs.trajectory |
Trajectory JointTrajectory PoseTrajectory (+ points) JointLimits concatenate TimeRepair |
robot_msgs.viz [viz] |
plot(msg) for every type, animate(*trajectories, path=...) |
robot_msgs.ros [ros] |
to_ros / from_ros (ROS 2 Jazzy via rosbags), write_bag / read_bag (mcap) |
Every message: == and hash by value, a short repr, replace(...), to_dict() /
from_dict(), save_npz / load_npz, pickling.
Conventions
SI units · quaternions (x, y, z, w) (MuJoCo/viser wxyz only through xyzw_to_wxyz) ·
Euler = ROS roll-pitch-yaw (fixed X, Y, Z) · a @ b applies b in a's frame ·
Header.stamp float seconds, trajectory t relative to it · Header.meta str → str · absent optional arrays are None.
The full contract, what we keep from ROS and what we drop, and how to extend: docs/DESIGN.md.
Develop
env -u VIRTUAL_ENV uv run --directory /home/bam/robot_msgs --isolated --extra test python -m pytest -q
Examples: examples/tour.py (above), examples/ur5e_pick.py (waypoints → minimum-jerk joint
trajectory → tool pose trajectory through UR5e FK), examples/gallery.py OUTDIR (every plot).
Metadata
Release files for robot-msgs 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| robot_msgs-0.1.0.tar.gz | 143.1 kB | Without provenance | Details for robot_msgs-0.1.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| robot_msgs-0.1.0-py3-none-any.whl | Python 3 | none | any | Details for robot_msgs-0.1.0-py3-none-any.whl |
Total release size: 247.3 kB
Release files / robot_msgs-0.1.0.tar.gz
| Download URL | robot_msgs-0.1.0.tar.gz |
|---|---|
| Size | 143.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
be783ed8ce80e260f6dbc62c5e7f5192c60d9c79cff9b94616033151114ea37e
|
|
BLAKE2b-256 checksum How to use checksums |
cdcbeb8bae853311ac7316f5627be80dec88738fea8b903e6329ed53b1cf7db7
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.13.7 {"installer":{"name":"uv","version":"0.13.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"26.04","id":"resolute","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / robot_msgs-0.1.0-py3-none-any.whl
| Download URL | robot_msgs-0.1.0-py3-none-any.whl |
|---|---|
| Size | 104.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
2de61baff0ad55b216f461e6b2554566b08e86e26bbc425340391b44c75ac892
|
|
BLAKE2b-256 checksum How to use checksums |
3e30fa11c1285421ca66e6d0b0a238428c9609b43a5a50870e052b771b6ce7a6
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.13.7 {"installer":{"name":"uv","version":"0.13.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"26.04","id":"resolute","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Security for robot-msgs 0.1.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.