简体中文 | English
This directory provides client-side code for the vla.cpp model-server. The client is only responsible for encoding the current observation as a TCP request, sending it to the server, and parsing the returned action chunk and timing information. Robot observation collection and action execution are handled by the upper-level platform / policy code.
All clients require the vla.cpp server to be running. The most common address is:
127.0.0.1:5555
For example, from the repository root:
bash robot_server/shell/launch_robot_server_mac_cpu.shIf you are using Windows, CUDA, or a different model checkpoint, use the corresponding script under robot_server/shell/. The only requirement is that the host/port match the client configuration.
The Python TCP client is located at:
robot_client/python/model_client.py
It provides:
health(): check whether the server is availablereset(): reset server-side cache/stateshutdown(): ask the server to exitpredict(observation): send an observation and return an action chunk
The minimal Python example is located at:
robot_client/examples/python/minimal_example.py
After starting the server, run:
python robot_client/examples/python/minimal_example.pyYou can also run a benchmark smoke test through the wrapper script:
export VLA_CPP_ROOT=/path/to/vla.cpp/robot.cpp
bash robot_client/shell/client_example.shNote:
client_example.shdepends on theVLA_CPP_ROOTenvironment variable.minimal_example.pyconnects to127.0.0.1:5555by default.- An observation must contain at least
images,state, andprompt.
The Python client accepts an observation as a dict:
{
"images": [
{
"name": "image",
"image": image_hwc_uint8,
}
],
"state": state_vector,
"prompt": "grab the block.",
}Images can be passed directly through image, or through pre-packed raw RGB fields:
{
"name": "observation.images.camera1",
"rgb_hwc_u8": rgb_bytes,
"width": 224,
"height": 224,
"stride_bytes": 224 * 3,
}model_client.py normalizes the input into contiguous RGB / HWC / uint8 bytes and sends it to the server using the vla.cpp TCP protocol.
ModelClient.predict() returns a ModelResponse:
| Field | Description |
|---|---|
chunk_size |
Number of action steps returned by the server in one response |
action_dim |
Dimension of each action step |
actions_flat |
Flat action buffer with length chunk_size * action_dim |
actions |
2D list with shape [chunk_size][action_dim] |
timings |
Per-stage timings returned by the server, such as vision_ms, llm_ms, and model_total_ms |
A typical usage pattern is to push response.actions into a queue and pop one action row per control-loop step:
response = client.predict(observation)
first_action = response.actions[0]The real-robot synchronous control loop uses robot_client/policy:
robot_client/policy/base_policy.py # BasePolicy / RobotPolicy
robot_client/policy/sync_loop.py # observe -> select_action -> send_action
robot_client/policy/sim_policy.py # Policy helper for simulation evaluation
Where:
BasePolicymanagesModelClient, the action queue, andselect_actionRobotPolicyconverts platform observations into model-server observationsSyncControlLoopconnects the platform and policy, and runs them at the target FPSSimPolicyreuses the server lifecycle and timing statistics for simulation evaluations such as LIBERO
The SO101 real-robot entry point is:
bash eval/lerobot_so101/script/shell/run_robot_client.shThe C++ client is located at:
robot_client/cpp/model_client.h
robot_client/cpp/model_client.cpp
The minimal C++ example is located at:
robot_client/examples/cpp/minimal_example.cpp
After starting the server, run:
export VLA_CPP_ROOT=/path/to/vla.cpp/robot.cpp
bash robot_client/shell/cpp_client_example.shConfigurable variables:
| Variable | Description |
|---|---|
VLA_CPP_ROOT |
Repository root, required by the script |
BUILD_DIR |
CMake build directory |
HOST / PORT |
model-server address |
BUILD_CLIENT |
Set to 1 to force re-configuring / rebuilding the C++ example |
CMAKE_BIN |
CMake executable |
Directory layout:
robot_client/
├── python/model_client.py # Python TCP client and protocol codec
├── cpp/model_client.{h,cpp} # C++ TCP client
├── examples/python/minimal_example.py # Minimal Python request example
├── examples/cpp/minimal_example.cpp # Minimal C++ request example
├── shell/client_example.sh # Python smoke-test wrapper
├── shell/cpp_client_example.sh # C++ example build/run wrapper
└── policy/
├── base_policy.py # BasePolicy / RobotPolicy
├── sim_policy.py # Simulation evaluation helper
└── sync_loop.py # Synchronous control loop
The overall call chain is:
platform.get_observation()
-> policy.build_observation()
-> ModelClient.predict()
-> policy.select_action()
-> platform.send_action()
For real robots, platform.send_action() converts the model output vector into {joint_name: value} according to action_keys. For simulation, the numpy action is usually passed directly to env.step().