Skip to content

Commit 222670b

Browse files
committed
formatting
1 parent 02c1c52 commit 222670b

1 file changed

Lines changed: 37 additions & 22 deletions

File tree

src/pycyphal2/__init__.py

Lines changed: 37 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,15 @@
55
66
Supports various transports such as Ethernet (UDP) and CAN FD with optional redundancy.
77
8-
## Installation
8+
# Installation
99
1010
Optional features inside the brackets can be removed if not needed; see `pyproject.toml` for the full list:
1111
1212
```
1313
pip install 'pycyphal2[udp,pythoncan]'
1414
```
1515
16-
## Usage
16+
# Usage
1717
1818
Set up a transport, make a node, publish and subscribe:
1919
@@ -40,34 +40,34 @@ async def main():
4040
Transport modules (`pycyphal2.udp`, `pycyphal2.can`) are imported separately
4141
so that only the needed dependencies are pulled in.
4242
43-
### Name resolution
43+
## Name resolution
4444
4545
The topic naming system shares many similarities with [ROS Names](https://wiki.ros.org/Names).
4646
4747
Name resolution is the process by which a topic name passed to `node.advertise()` or `node.subscribe()` is resolved to a topic name as used on the Cyphal network.
48+
There exist 4 kinds of topic names in Cyphal:
4849
49-
There exist 4 kinds of topic names in Cyphal, used effectively they allow the developer to split up complex systems into smaller sub-systems, simplifying development and debugging.
50+
<details markdown="1">
51+
<summary>Relative Name</summary>
5052
51-
#### 1. Relative Name
52-
53-
A relative name is a name that does not start with '/' or `~/`.
53+
A relative name is a name that does not start with `/` or `~/`.
5454
5555
```
5656
sensor/temperature
5757
cmd_vel
5858
camera/image_raw
5959
```
6060
61-
It's resolved name is prefixed with the node namespace.
61+
Its resolved name is prefixed with the node namespace.
6262
6363
| Input name | Namespace | Home | Resolved name |
6464
| ----------------- | --------- | ---- | --------------------- |
6565
| `foo` | `ns` | `me` | `ns/foo` |
6666
| `foo/bar` | `ns` | `me` | `ns/foo/bar` |
6767
68-
Use case: Use relative names for topics that are specific to a node, but might be reused across multiple nodes.
68+
*Use case:* Use relative names for topics that are specific to a node, but might be reused across multiple nodes.
6969
70-
Example: A robot contains 4 motor controllers of the same type, each has its own namespace (`motor_1`, `motor_2`, `motor_3`, `motor_4`).
70+
*Example:* A robot contains 4 motor controllers of the same type, each has its own namespace (`motor_1`, `motor_2`, `motor_3`, `motor_4`).
7171
Using relative names, the application code is the same for all 4 motor controllers, however the topics are resolved differently based on the node namespace.
7272
7373
| Input name | Namespace | Home | Resolved name |
@@ -77,7 +77,10 @@ async def main():
7777
| `speed` | `motor_3` | `robot` | `motor_3/speed` |
7878
| `speed` | `motor_4` | `robot` | `motor_4/speed` |
7979
80-
#### 2. Absolute Name
80+
</details>
81+
82+
<details markdown="1">
83+
<summary>Absolute Name</summary>
8184
8285
An absolute name starts with `/`.
8386
@@ -86,14 +89,14 @@ async def main():
8689
/diagnostics/status
8790
```
8891
89-
It ignores the node namespace.
92+
Its resolved name is simply the same as the input name, ignoring both the node namespace and home.
9093
9194
| Input name | Namespace | Home | Resolved name |
9295
| ----------------- | --------- | ---- | ------------------ |
9396
| `foo` | `ns` | `me` | `foo` |
9497
| `foo/bar` | `ns` | `me` | `foo/bar` |
9598
96-
Use case: Use absolute names for topics that are shared across multiple nodes.
99+
Use case: Use absolute names for topics that are *not* specific to a node and might be reused across multiple nodes.
97100
98101
Example: Shared system topics like `/log`, since multiple nodes may publish to the same topic.
99102
Conversely, topics like `/battery_voltage` that might be sourced from multiple nodes but need one single source of truth for other nodes like the motor controllers to subscribe to.
@@ -103,15 +106,20 @@ async def main():
103106
| `/log` | `cpu` | `robot` | `/log` |
104107
| `/battery_voltage` | `battery_1` | `robot` | `/battery_voltage` |
105108
106-
#### 3. Homeful Name
109+
</details>
110+
111+
<details markdown="1">
112+
<summary>Homeful Name</summary>
107113
108114
A homeful name starts with `~` of `~/`.
109115
110116
```
111117
~/config
112118
```
113119
114-
Note that the node namespace is ignored. Also note that `~foo` is not homeful and resolves as relative name to `ns/~foo` (this is confusing so don't use this).
120+
Its resolved name consists of the home and the input name, with the node namespace ignored. Note that `~foo` is not homeful and resolves as relative name to `ns/~foo` (this is confusing so don't use this).
121+
122+
Proposal: both `~` and `~foo` should not be allowed.
115123
116124
| Input name | Namespace | Home | Resolved name |
117125
| --------------------- | --------------- | ------- | ------------------ |
@@ -123,7 +131,10 @@ async def main():
123131
124132
Example: We want to configure an antenna to transmit at a specific frequency. The antenna node has a `~/config/frequency` topic that we can publish to.
125133
126-
#### 4. Pattern Name
134+
</details>
135+
136+
<details markdown="1">
137+
<summary>Pattern Name (only for subscribing)</summary>
127138
128139
A pattern name contains wildcard `*` (matches any _single_ name segment)
129140
@@ -143,7 +154,11 @@ async def main():
143154
Example: `*/battery_pct` to subscribe to all nodes publishing battery data, of which there may be multiple per vehicle.
144155
'logs/>' to subscribe to all topics publishing under '/logs' which may contain 'log_info', 'log_warning', 'log_error' topics.
145156
146-
#### Extra functions
157+
</details>
158+
159+
Used effectively they allow to split up complex systems into smaller sub-systems simplifying development and debugging.
160+
161+
### Extra functions
147162
148163
*Topping* is the process by which a unique subject ID is assigned upon initialization.
149164
For some applications that require a high level of reliability, determinism is required and can be achieved by using `#` to pin a topic to a specific subject ID.
@@ -186,7 +201,7 @@ async def main():
186201
187202
See also :meth:`Node.remap`.
188203
189-
### Publish
204+
## Publish
190205
191206
Publication is best-effort by default. Pass `reliable=True` when publishing to retry delivery until
192207
acknowledged by every known subscriber or until the deadline; if the remote side does not acknowledge in time,
@@ -197,7 +212,7 @@ async def main():
197212
await pub(Instant.now() + 1.0, b"payload", reliable=True)
198213
```
199214
200-
### Subscribe
215+
## Subscribe
201216
202217
Subscriptions normally yield messages as soon as they arrive. Set `reordering_window` [seconds] on
203218
:meth:`Node.subscribe` to allow delaying out-of-order messages to reconstruct the original publication order.
@@ -219,7 +234,7 @@ async def main():
219234
print(topic.name, captures) # [('engine', 1)], where 1 is the pattern segment index
220235
```
221236
222-
### RPC & streaming
237+
## RPC & streaming
223238
224239
RPC is layered directly on top of pub/sub. Use :meth:`Publisher.request` to publish a message that expects
225240
responses, and use :attr:`Arrival.breadcrumb` on the subscriber side to send a unicast reply back to the requester.
@@ -239,7 +254,7 @@ async def main():
239254
await arrival.breadcrumb(Instant.now() + 1.0, b"chunk-2", reliable=True)
240255
```
241256
242-
### Topic pinning
257+
## Topic pinning
243258
244259
Topics may be pinned to a specific subject-ID using `name#1234` to bypass automatic assignment.
245260
This is useful for applications where a high degree of determinism is required and for Cyphal/CAN v1.0 interoperability.
@@ -255,7 +270,7 @@ async def main():
255270
Old Cyphal/CAN v1.0 nodes do not participate in the topic discovery protocol,
256271
so topics joined only by such nodes are not discoverable by pattern subscribers.
257272
258-
## Remarks
273+
# Remarks
259274
260275
Cyphal does not define a serialization format. Previous versions used to define the DSDL format but it has been
261276
extracted into an independent project, and Cyphal was made serialization-agnostic in v1.1+.

0 commit comments

Comments
 (0)