# Name channels and units

# Name channels and units

Give each signal a readable name and unit, and see how it is drawn. A channel
is one signal from one input, named by a path like `/rig/pressure`,
`/cam/front` or `/arm/joint/position_deg`.

## Kinds

What a channel carries decides which tile (one box on **Live**) draws it.

| Kind | What it is | Drawn as | Set by |
|---|---|---|---|
| `scalar` | a number or true/false | a trace on Live, a column in Replay | Phloem |
| `text` | a line of text | a text row | Phloem |
| `image` | a camera frame | a picture tile | the source |
| `segmentation_image` | a per-pixel mask over a frame | overlay on the frame | the source |
| `vector` | a list of numbers that belong together | a waveform tile | the source |
| `points3d` | a point cloud | the 3D scene | the source |
| `boxes2d` | boxes drawn on a camera frame | overlay on the frame | the source |
| `boxes3d` | boxes in 3D | the 3D scene | the source |
| `transform3d` | where something sits and how it is turned | places the others in 3D | the source |
| `line_strips3d` | paths, trajectories, footstep plans, polygons | lines in the 3D scene | the source |
| `arrows3d` | vectors from a point — velocity, force, a heading | arrows in the 3D scene | the source |
| `poses3d` | positions with an orientation — a robot's pose, waypoints | small axis triads in the 3D scene | the source |
| `mesh3d` | a triangle mesh or a 3D model file (glTF, OBJ, STL) | a solid in the 3D scene | the source |
| `ellipsoids3d` | spheres and ellipsoids | shapes in the 3D scene | the source |
| `cylinders3d` | cylinders | shapes in the 3D scene | the source |
| `text3d` | labels pinned to points in space | text over the 3D scene | the source |
| `grid_map` | an occupancy grid, costmap or height map | a raster laid in the 3D scene | the source |
| `pinhole` | a camera's field of view | a frustum in the 3D scene | the source |
| `depth_image` | distance per pixel | a depth-shaded picture tile | the source |
| `geo_points` | GPS fixes | dots and a track on the Map | the source |
| `geo_line_strings` | a route or track on the Earth | a line on the Map | the source |
| `points2d` | keypoints on a camera frame | overlay on the frame | the source |
| `line_strips2d` | lines and circles on a camera frame | overlay on the frame | the source |
| `text2d` | labels on a camera frame | overlay on the frame | the source |

Phloem recognises numbers and text. Everything else arrives as bytes, so the
source must say which kind it is. Recordings do this through their topic types:
a ROS path lands as `line_strips3d`, a Foxglove point cloud as `points3d`, a GPS
fix as `geo_points`.

When the machine is online, the Map draws OpenStreetMap streets. Pick another
source with the tile button on the panel. Offline, the track still draws over a
plain grid.

## Nothing is drawn

A channel of bytes with no kind still records and replays, but nothing draws
it.

| Comes from | Fix |
|---|---|
| a **Push endpoint** | say `image` or `segmentation_image` in the body — [Send your own data](https://phloem.ai/docs/inputs/push/) |
| a **connector** | the connector decides; if it says nothing, raise it there |
| a recording | the file's own topic types decide it |

> **Note:** A kind takes effect on the channel's next sample. You don't need to
> re-import anything.

## Paths

- A missing leading `/` is added: `temp1` becomes `/temp1`. Empty segments
  (`//cam`, a trailing `/`) are refused.
- A structured message becomes one channel per field
  (`/imu/data/orientation/x`), and an array one per position
  (`/scan/ranges/0`).
- Where you type a path, as in a pipeline step or Trellis rule, `**` matches
  everything below it: `/motor/**`.
- Names and units belong to the **path**, not the input. Swap the box behind
  `/daqmx/Dev1/ai0` and `rig pressure` stays with the path.

## Name a channel, set its unit

**Add input** has a **Channels** section with one row per channel: the end of
the path, a **name** box and a **unit** box. The same rows show when you edit
the input later.

1. Type the name you want to see, like `rig pressure`.
2. Type the unit, like `bar`.
3. Click away from the box to save. **Add & start** does not save it.

Your unit replaces the device's own unit everywhere. Clear the box to use the
device's unit again.

A board that can list its channels fills the rows straight away. Other inputs
fill them once data arrives. Until then the section reads *No channels yet —
start the input and they will appear here, ready to name*.

## Waveform tiles

A waveform is one channel holding a list of numbers at one moment, with a label
for each slot. Six joint angles are one channel on a `J1`…`J6` axis, not six
channels. A source calls this kind `vector`.

- Named slots draw as bars, a continuous range as a line. The labels decide.
- `peak hold` keeps each slot's highest value on screen, so you don't miss a
  spike.
- In Replay you see the sample **at the cursor**, or *No sample at this
  cursor.* It never shows a newer one instead.

A robot's `sensor_msgs/JointState` is **not** a waveform. Each joint is its own
number channel, named by the robot: `/joint_states/position/left_hip_pitch`,
`/joint_states/effort/left_hip_pitch`. A safety limit can then watch one joint,
and a chart can pick the joints it wants. If the message has no names, the
channels are numbered (`…/position/0`, `/1`, …).

You cannot send a waveform by hand. It comes from a source that makes one, or
from a pipeline step that builds one.

A safety limit checks one number, so it cannot watch a whole waveform. Put the
limit on a number channel instead. A **Derive channel** step on **Pipelines**
makes one from the raw signal.
