Python PDU communication library for the Hakoniwa simulator. Provides a unified transport layer where RPC and Pub/Sub (topics) run seamlessly over WebSocket. For high-speed use cases, a Shared Memory (SHM) backend is also available. The architecture is extensible to Zenoh, enabling scalable and distributed systems. Binary β JSON β Python type conversion is built-in, reducing boilerplate to a minimum.
- Unified layer: RPC and Pub/Sub integrated on top of WebSocket
- Automatic type conversion: safely convert between binary, JSON, and Python types with offset definitions
- Transport flexibility: choose between WebSocket, Shared Memory (SHM), and extensible backends such as Zenoh
- Explicit & secure connections: WebSocket URIs (
ws://...) clearly define communication scope - Event-driven & polling support: register handlers or poll buffers as needed
- Ready-to-run samples: minimal examples for
Twist(topic) andAddTwoInts(RPC) included
pip install hakoniwa-pdu
pip show hakoniwa-pdu # check versionSpecify the directory containing .offset files for PDU conversion:
export HAKO_BINARY_PATH=/your/path/to/offsetDefault path if unset:
/usr/local/lib/hakoniwa/hako_binary/offset
Example 1: WebSocket Topic (
geometry_msgs/Twistpublish β subscribe)
- Publisher (server)
python examples/topic/websocket/remote_publisher.py \
--uri ws://localhost:8080 \
--pdu-config examples/pdu_config.json \
--service-config examples/service.json- Subscriber (client)
python examples/topic/websocket/remote_subscriber.py \
--uri ws://localhost:8080 \
--pdu-config examples/pdu_config.json \
--service-config examples/service.json- Output
[INFO] Received Twist: linear.x=0 angular.z=0
[INFO] Received Twist: linear.x=1 angular.z=1
Example 2: WebSocket RPC (
AddTwoIntsservice)
- RPC Server
python examples/rpc/websocket/remote_rpc_server.py \
--uri ws://localhost:8080 \
--pdu-config examples/pdu_config.json \
--service-config examples/service.json- RPC Client
python examples/rpc/websocket/remote_rpc_client.py \
--uri ws://localhost:8080 \
--pdu-config examples/pdu_config.json \
--service-config examples/service.json- Output
Response: 3
Server:
server_manager.register_handler_pdu_data(on_pdu)
def on_pdu(client_id, packet):
...Client:
client_manager.register_handler_pdu_data(on_pdu)
def on_pdu(packet):
...Polling via contains_buffer() / get_buffer() is also available.
hakoniwa_pdu/
βββ pdu_manager.py
βββ impl/
β βββ icommunication_service.py
β βββ websocket_communication_service.py
β βββ websocket_server_communication_service.py
β βββ shm_communication_service.py
β βββ pdu_convertor.py
β βββ hako_binary/
βββ rpc/
β βββ ipdu_service_manager.py
β βββ protocol_client.py
β βββ protocol_server.py
β βββ auto_wire.py
β βββ remote/
β βββ shm/
βββ resources/
β βββ offset/
βββ examples/
hako_launcher.py orchestrates multiple Hakoniwa assets described in a JSON file. The
launcher handles environment preparation, process supervision, and optional
notifications when an asset exits unexpectedly.
# Basic usage (immediate mode)
python -m hakoniwa_pdu.apps.launcher.hako_launcher path/to/launch.json
# Immediate mode with background exit (skip monitoring loop)
python -m hakoniwa_pdu.apps.launcher.hako_launcher path/to/launch.json --no-watch
# Interactive control (serve mode)
python -m hakoniwa_pdu.apps.launcher.hako_launcher path/to/launch.json --mode serve- Immediate mode (default) performs
activate β hako-cmd start β watch.- Assets whose
activation_timingis"before_start"are spawned first. - After
hako-cmd startcompletes successfully, assets with"after_start"are started. - Unless
--no-watchis specified, the launcher keeps monitoring child processes. If any asset stops, every remaining asset is terminated.
- Assets whose
- Serve mode keeps the process alive and accepts commands via STDIN.
Available commands:
activate,start,stop,reset,terminate,status,quit/exit.
Set HAKO_PDU_DEBUG=1 to enable debug logging from the launcher modules.
The schema is provided at
src/hakoniwa_pdu/apps/launcher/schemas/launcher.schema.json. A minimal
configuration consists of a version header, optional defaults, and at least one
asset definition.
| Key | Description |
|---|---|
version |
Free-form version string for the specification.γF:src/hakoniwa_pdu/apps/launcher/model.pyβ L82-L90γ |
defaults |
Shared defaults applied to every asset when the field is omitted at the asset level. Paths are resolved relative to the launch file.γF:src/hakoniwa_pdu/apps/launcher/loader.pyβ L47-L91γ |
assets |
Array of process definitions. Launch order is automatically sorted by depends_on while preserving the original order when there is no dependency.γF:src/hakoniwa_pdu/apps/launcher/model.pyβ L112-L167γ |
notify |
Optional notification that fires when an asset exits or the launcher aborts. Supports webhook and exec variants.γF:src/hakoniwa_pdu/apps/launcher/model.pyβ L58-L80γγF:src/hakoniwa_pdu/apps/launcher/hako_monitor.pyβ L83-L121γ |
cwd,stdout,stderr: default working directory and log sinks for assets. These support${asset},${timestamp}, and${base_dir}placeholders. The loader resolves relative paths using the directory of the launch file.γF:src/hakoniwa_pdu/apps/launcher/loader.pyβ L30-L91γγF:src/hakoniwa_pdu/apps/launcher/hako_monitor.pyβ L19-L35γstart_grace_sec: minimum time (seconds) an asset must stay alive after spawn to be considered healthy (default5.0).γF:src/hakoniwa_pdu/apps/launcher/model.pyβ L40-L54γdelay_sec: delay inserted before launching the next asset (default3.0).γF:src/hakoniwa_pdu/apps/launcher/model.pyβ L40-L54γenv: environment operations merged into the runtime environment in three stages: OS env β defaults.env β asset.env. Keysset,prepend,append, andunsetare supported, andlib_pathautomatically maps toLD_LIBRARY_PATH/DYLD_LIBRARY_PATH/PATHdepending on the platform.γF:src/hakoniwa_pdu/apps/launcher/model.pyβ L12-L37γγF:src/hakoniwa_pdu/apps/launcher/envmerge.pyβ L1-L103γ
Environment variables written as ${VAR} or ${VAR:-default} inside the JSON
are resolved when the file is loaded. Placeholders ${asset} and ${timestamp}
are preserved for runtime expansion inside log paths and environment settings.γF:src/hakoniwa_pdu/apps/launcher/loader.pyβ L18-L67γ
| Field | Description |
|---|---|
name |
Asset identifier. Used for dependency checks and placeholders.γF:src/hakoniwa_pdu/apps/launcher/model.pyβ L56-L115γ |
command / args |
Executable and argument vector passed to the process.γF:src/hakoniwa_pdu/apps/launcher/hako_monitor.pyβ L40-L77γ |
cwd |
Working directory. Defaults to the launch file directory or defaults.cwd.γF:src/hakoniwa_pdu/apps/launcher/loader.pyβ L47-L91γ |
stdout / stderr |
Optional log file destinations. Directories are created automatically and support placeholders. Leave null to inherit the parent stream.γF:src/hakoniwa_pdu/apps/launcher/hako_asset_runner.pyβ L60-L117γ |
delay_sec |
Wait time before the next asset starts (overrides defaults.delay_sec).γF:src/hakoniwa_pdu/apps/launcher/model.pyβ L94-L107γ |
activation_timing |
before_start launches prior to hako-cmd start; after_start launches only after a successful hako-cmd start.γF:src/hakoniwa_pdu/apps/launcher/model.pyβ L94-L107γγF:src/hakoniwa_pdu/apps/launcher/hako_launcher.pyβ L28-L70γ |
depends_on |
List of other asset names that must start before this one. Cycles are rejected during load.γF:src/hakoniwa_pdu/apps/launcher/model.pyβ L112-L167γ |
start_grace_sec |
Asset-specific stability grace period overriding defaults.start_grace_sec.γF:src/hakoniwa_pdu/apps/launcher/model.pyβ L94-L107γγF:src/hakoniwa_pdu/apps/launcher/hako_monitor.pyβ L40-L77γ |
env |
Environment overrides merged on top of defaults.env. Supports ${asset}, ${timestamp}, and ${ENV:VAR} substitutions at runtime.γF:src/hakoniwa_pdu/apps/launcher/envmerge.pyβ L14-L103γ |
type: "exec"executes a local command when the launcher aborts (placeholders${asset}and${timestamp}are available).γF:src/hakoniwa_pdu/apps/launcher/model.pyβ L58-L80γγF:src/hakoniwa_pdu/apps/launcher/hako_monitor.pyβ L83-L121γtype: "webhook"issues an HTTP POST with the event name, asset, and timestamp. Use for integrations such as Slack or monitoring dashboards.γF:src/hakoniwa_pdu/apps/launcher/model.pyβ L58-L80γγF:src/hakoniwa_pdu/apps/launcher/hako_monitor.pyβ L83-L121γ
Refer to the sample JSON provided above for a real-world configuration that launches a drone asset together with supporting services.
- Orchestrates PDU buffers and delegates to a transport (
ICommunicationService). - Direct I/O:
declare_pdu_for_read/writeβflush_pdu_raw_data()/read_pdu_raw_data(). - For RPC: extended via
rpc.IPduServiceManager(handlesregister_client,start_rpc_service, etc.).
ICommunicationServicedefines the transport API.WebSocketCommunicationService/WebSocketServerCommunicationService: WebSocket backend (explicit URI-based connection, simple & secure).ShmCommunicationService: high-speed shared memory backend.- Pluggable design: additional transports (e.g., Zenoh) can be integrated without changing application code.
IPduServiceManagerfamily provides RPC APIs (client/server).protocol_client.py/protocol_server.py: user-friendly helpers.auto_wire.py: auto-loads generated converters.remote/: WebSocket managers.shm/: SHM managers.
classDiagram
class PduManager
PduManager --> ICommunicationService : uses
PduManager --> CommunicationBuffer
PduManager --> PduConvertor
PduManager --> PduChannelConfig
class ICommunicationService {
<<interface>>
}
class WebSocketCommunicationService
class WebSocketServerCommunicationService
class ShmCommunicationService
ICommunicationService <|.. WebSocketCommunicationService
ICommunicationService <|.. WebSocketServerCommunicationService
ICommunicationService <|.. ShmCommunicationService
class IPduServiceManager {
<<abstract>>
}
PduManager <|-- IPduServiceManager
class IPduServiceClientManager
class IPduServiceServerManager
IPduServiceManager <|-- IPduServiceClientManager
IPduServiceManager <|-- IPduServiceServerManager
class RemotePduServiceBaseManager
RemotePduServiceBaseManager <|-- RemotePduServiceClientManager
RemotePduServiceBaseManager <|-- RemotePduServiceServerManager
IPduServiceManager <|-- RemotePduServiceBaseManager
class ShmPduServiceBaseManager
ShmPduServiceBaseManager <|-- ShmPduServiceClientManager
ShmPduServiceBaseManager <|-- ShmPduServiceServerManager
IPduServiceManager <|-- ShmPduServiceBaseManager
- π GitHub: https://github.com/hakoniwalab/hakoniwa-pdu-python
- π Hakoniwa Lab: https://hakoniwa-lab.net
For detailed API usage: β‘οΈ API Reference (api-doc.md)
MIT License β see LICENSE
{ "version": "0.1", "defaults": { "cwd": ".", "stdout": "logs/${asset}.out", "stderr": "logs/${asset}.err", "start_grace_sec": 1, "delay_sec": 3, "env": { "prepend": { "PATH": ["/usr/bin"] } } }, "assets": [ { "name": "drone", "command": "linux-main_hako_aircraft_service_px4", "args": ["127.0.0.1", "4560"], "activation_timing": "before_start" } ] }