Skip to content

Latest commit

 

History

9 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

foxglove-ros-client-py

A Python client for foxglove_bridge with a roslibpy-compatible API surface. It speaks the Foxglove WebSocket protocol instead of the rosbridge JSON protocol.

The canonical import package is foxglove_ros_client:

from foxglove_ros_client import Ros, Topic, Message, Service, ServiceRequest, Param

Status

This is an early runtime-focused implementation for ROS 2 systems exposed by foxglove_bridge.

Supported:

  • Ros(host, port=None, is_secure=False, headers=None, ca_cert_file=None) with run(), run_forever(), close(), terminate(), on(), off(), on_ready(), call_later(), and is_connected.
  • Topic(...).subscribe(), unsubscribe(), publish(), advertise(), unadvertise().
  • Service(...).call() with blocking and callback forms.
  • Param(...).get() and set() through Foxglove parameter operations.
  • Rosapi-style discovery helpers backed by Foxglove advertisements: get_topics(), get_topic_type(), get_topics_for_type(), get_services(), get_service_type(), get_services_for_type(), get_message_details(), get_service_request_details(), get_service_response_details(), get_nodes(), get_node_details(), and action-server discovery.
  • ROS 2 ActionClient.send_goal(), cancel_goal(), and wait_goal() when the bridge advertises hidden action endpoints. Use Ros.wait_for_action() to wait until a specific action is ready before sending a goal.
  • Full parameter listing via get_params() and best-effort parameter deletion via delete_param() / Param.delete() when the server accepts parameter updates.
  • ROS 1-style foxglove_ros_client.ros1.actionlib.ActionClient, Goal, and SimpleActionServer over action topics.
  • TFClient over /tf and /tf_static, including fixed-frame resolution across parent/child transform chains.
  • Dict-like Message, ServiceRequest, ServiceResponse, Goal, Result, Feedback, Time, Header, and foxglove_ros_client.ros2.Header.
  • A foxglove-ros-client-py command-line entry point with roslibpy-style topic, msg, service, srv, and param subcommands.

Not supported:

  • Client-side service advertisement. foxglove_bridge does not expose a WebSocket protocol for Python clients to serve ROS services.

Notes:

  • get_nodes() and get_node_details() use Foxglove connection graph updates. They return data only when the server advertises the connectionGraph capability.
  • get_params() requests all currently set parameters with getParameters. Parameter deletion is represented as a setParameters request with an unset value; a ROS bridge or node can still reject the change for normal middleware reasons such as read-only or undeclared parameters.

Install From Source

git clone https://github.com/PickNikRobotics/foxglove-ros-client-py.git
python -m pip install ./foxglove-ros-client-py

Connect

Start the ROS 2 Foxglove bridge:

ros2 launch foxglove_bridge foxglove_bridge_launch.xml port:=8765

For ROS 2 actions, start the bridge with hidden topics and services included:

ros2 launch foxglove_bridge foxglove_bridge_launch.xml port:=8765 include_hidden:=true

Foxglove exposes ROS 2 actions through the hidden /_action/* services and topics. This differs from rosbridge/actionlib topic wiring; ActionClient uses Foxglove service calls to send_goal, get_result, and cancel_goal.

Use the familiar API shape:

from foxglove_ros_client import Message, Ros, Topic

ros = Ros("localhost", 8765)
ros.run()

listener = Topic(ros, "/chatter", "std_msgs/msg/String")
listener.subscribe(lambda msg: print(msg["data"]))

talker = Topic(ros, "/python/chatter", "std_msgs/msg/String")
talker.publish(Message({"data": "hello from Python"}))

Wrap run() and subsequent work in try / finally and call close() from the finally block. close() also cancels a connection attempt that times out before the WebSocket opens.

Authenticated connections

Pass WebSocket handshake headers to Ros when the endpoint requires authentication:

import os

from foxglove_ros_client import Ros

ros = Ros(
    "robot.example",
    3201,
    is_secure=True,
    headers={"Authorization": f"Bearer {os.environ['MOVEIT_FRONTEND_KEY']}"},
    ca_cert_file="/path/to/runtime-cert-or-ca.pem",
)
ros.run()

ca_cert_file is optional when the endpoint certificate is already trusted by the client runtime. Keep certificate verification enabled.

std_msgs/String and std_msgs/msg/String are both accepted. Subscription and service responses are decoded from CDR using schemas advertised by the bridge. Publishing uses CDR when a matching schema has been advertised, otherwise it falls back to Foxglove's JSON client-channel encoding.

Development

python -m venv .venv
. .venv/bin/activate
python -m pip install -e ".[test]"
pytest
python -m build

The command-line helper can be run after installation:

foxglove-ros-client-py -r localhost -p 8765 topic list

Live Check

The live smoke test exercises topic subscription, publishing, parameter reads, service discovery, and action discovery without sending action goals:

python examples/live_bridge_check.py --url ws://localhost:8765

Service calls are optional and generic:

python examples/live_bridge_check.py \
  --url ws://localhost:8765 \
  --service-name /example_service \
  --service-type example_interfaces/srv/Trigger \
  --service-request-json '{}'

Action execution is intentionally double-gated:

python examples/live_bridge_check.py \
  --url ws://localhost:8765 \
  --action-mode send-goal \
  --action-name /example_action \
  --action-type example_interfaces/action/Fibonacci \
  --action-goal-json '{"order": 5}' \
  --allow-action-execution

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages