JointTrajectory
Joint-space motion keyed by joint name. Every per-sample array is (N, J).
Full docstring
Layer anything else you need to send along (gains, feed-forward torque, modes) as `channels`, and per-joint bounds as `limits`.
Preview
The figure robot_msgs.viz.plot(example) draws for the example below.

Fields
| Name | Type | Default |
|---|---|---|
t | Array | required |
channels | Mapping[str, Array] | {} |
header | Header | Header() |
joint_names | tuple[str, ...] | required |
positions per sample | Array | required |
velocities per sample | Array | None | None |
accelerations per sample | Array | None | None |
effort per sample | Array | None | None |
limits | JointLimits | None | None |
Example
One instance from the package's own test catalog; the output is its real repr().
JointTrajectory(N=11, t=[0 … 1] s, channels={'kp': float64[11×3], 'mode': int64[11]}, header=Header(stamp=12.0, frame_id='base_link'), joint_names=('j1', 'j2', 'j3'), positions=float64[11×3], velocities=float64[11×3], limits=JointLimits(joint_names=('j1', 'j2', 'j3'), max_velocity=[2., 2., 2.], max_jerk=[50., 50., 50.]))to_dict() as JSON
{
"_type": "trajectory/JointTrajectory",
"t": {
"dtype": "<f8",
"shape": [11],
"data": [0.0, 0.1, 0.2, 0.30000000000000004, 0.4, 0.5, 0.6000000000000001, 0.7000000000000001, 0.8, 0.9, 1.0]
},
"channels": {
"kp": {
"dtype": "<f8",
"shape": [11, 3],
"data": [40.0, 40.0, 40.0, 40.0, 40.0, 40.0, 40.0, 40.0, 40.0, 40.0, 40.0, 40.0, 40.0, 40.0, 40.0, 40.0, "… 17 more values"]
},
"mode": {
"dtype": "<i8",
"shape": [11],
"data": [0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1]
}
},
"header": {
"_type": "std/Header",
"stamp": 12.0,
"frame_id": "base_link",
"meta": {}
},
"joint_names": ["j1", "j2", "j3"],
"positions": {
"dtype": "<f8",
"shape": [11, 3],
"data": [2.0409191213851825, -2.5556650313141818, 0.41809884672577885, -0.5677696061279298, -0.45264929211044586, -0.2155971630897659, -2.019986129147251, -0.23193237764418947, -0.8652130762749417, 3.3229995166448827, 0.22578661322792176, -0.3526307943415954, -0.2812874181513504, -0.6680463461089501, -1.0551505512051214, -0.39080097723465473, "… 17 more values"]
},
"velocities": {
"dtype": "<f8",
"shape": [11, 3],
"data": [0.5803500161908991, 0.09151670328235219, 0.6701043548284794, -2.8281623068437627, 1.02130681750008, -0.9596447598081417, -1.6686198426559695, 0.27644575952099965, 0.7005448853493901, -0.4447674556827841, -1.0764058401008076, 0.026124833534033623, -0.05274730824287927, 1.4055981660180925, 0.7474079874793504, 0.19381564626462, "… 17 more values"]
},
"accelerations": null,
"effort": null,
"limits": {
"_type": "trajectory/JointLimits",
"joint_names": ["j1", "j2", "j3"],
"min_position": null,
"max_position": null,
"max_velocity": {
"dtype": "<f8",
"shape": [3],
"data": [2.0, 2.0, 2.0]
},
"max_acceleration": null,
"max_jerk": {
"dtype": "<f8",
"shape": [3],
"data": [50.0, 50.0, 50.0]
},
"max_effort": null
}
}Long arrays are cut after 16 values and say so with “…”.
Functions
Constructors
Classmethods and staticmethods: ways to build one.
from_joint_states(
states: Sequence[JointState],
**static: object,
) -> JointTrajectoryA recorded trajectory from a log of JointStates (stamps become t).
from_points(
points: Sequence[TrajectoryPoint],
**static: Any,
) -> TrajectoryTStack points back into one trajectory; static sets the per-trajectory fields.
from_samples(
t: Any,
duplicate_times: DuplicateTimes,
**fields: Any,
) -> tuple[TrajectoryT, TimeRepair]Build from recorded samples whose stamps may repeat or step back; say what changed.
Properties
Read-only views computed from the fields.
dt: floatThe fixed sample step. Raises on a non-uniform trajectory rather than guess.
sample_names: tuple[str, ...]Names of every per-sample array that is set: typed fields, then channels.
Methods
Return new values; messages are never mutated.
joint(name: str) -> JointTrajectoryOne joint, still a JointTrajectory (so plotting, resampling etc. all work).
joint_state_at(
time: float,
extrapolate: Extrapolation = 'raise',
) -> JointStateThe commanded state at time as a sensor JointState on the header's clock.
limit_violations(limits: JointLimits | None = None) -> tuple[str, ...]Human-readable worst violation per joint and bound; empty when within limits.
select(names: Sequence[str]) -> JointTrajectoryOnly names, in that order. Channels are per-sample, so they are kept whole.
time_scaled(factor: float) -> JointTrajectoryThe same path, factor times slower (factor < 1 is faster).
with_derivatives(*, overwrite: bool = False) -> JointTrajectoryFill missing velocities/accelerations by finite differences on the real time grid.
at(
time: float,
extrapolate: Extrapolation = 'raise',
) -> TrajectoryPointThe point at time, interpolated per field (sample(interp=...)).
is_uniform(rtol: float = 1e-06) -> boolTrue when every sample step equals the mean step within rtol.
rebased() -> TrajectoryTSame trajectory with t[0] == 0; the offset moves into header.stamp.
resample(
times: Any = None,
dt: float | None = None,
extrapolate: Extrapolation = 'raise',
) -> TrajectoryTThe trajectory at new times, or on a fixed dt grid from start_time.
time_shifted(seconds: float) -> TrajectoryTEvery sample seconds later (earlier if negative).
to_dict
from Msgto_dict() -> dict[str, Any]JSON-safe dict with a "_type" key; arrays keep their dtype and shape.
to_points() -> tuple[TrajectoryPoint, ...]Array-of-structs view (what ROS puts on the wire).
window(start: float, end: float) -> TrajectoryTSamples with start <= t <= end, as a view.
Operators
Python operators and protocols the type supports.
__getitem__(key: Any) -> Anystr → a field's array · int → a point · slice, mask, indices → a trajectory.