How to use ROS in Brian
Setup
To enable ROS integration in your Brian simulation, you need to configure Brian to use Brian2ROS. At the beginning of your script, include the following line:
set_device("ros_standalone", directory="src/src/brian_project", debug=True)
Parameters:
directory: Path where the Brian2ROS files will be installed.debug: (Optional) Enables debug messages. Defaults toFalse.
Additional options are available to customize how Brian2ROS behaves:
Interface
By default, an interface window is displayed when launching a simulation. If you want to disable the interface and start the simulation directly (useful for embedded or headless execution), add the following line:
prefs.devices.ros_standalone.interface = False
This is particularly helpful when running code on embedded systems or in automated pipelines.
CycloneDDS Integration
Brian2ROS supports integration with CycloneDDS for communication with a physical robot. To enable this, add the following lines:
prefs.devices.ros_standalone.cyclonedds = True
prefs.devices.ros_standalone.network_interface = 'wlxf07959eb0bcf'
prefs.devices.ros_standalone.list_address_ip = ['10.42.0.1', '10.42.0.103']
⚠️ Make sure your robot is configured with the same IP setup and network interface.
This setup is especially useful when running the simulation inside a Docker container.
Publisher
In ROS 2, a publisher is a node component responsible for sending messages to a specific topic. It periodically generates and broadcasts data (e.g., sensor values, simulation outputs, control commands) that can be received by other nodes subscribing to that topic.
In the context of Brian2ROS, setting up a publisher is straightforward. You can define a publisher by simply creating an instance of the Publisher class.
Example: Basic Publisher
motor_commands = Publisher(
name="wheel",
topic="cmd_vel",
topic_type="geometry_msgs/msg/Twist",
input={"linear.x": 0.26, "angular.z": 1.82},
rate=500,
reset_values={"linear.x": 0.0, "angular.z": 0.0},
header=header
)
Parameters:
name: Internal name of the publisher.topic: ROS topic to publish to.topic_type: Full ROS message type.input: Dictionary mapping message fields to fixed values or Brian variables.rate: Publication frequency in Hz.reset_values: Values to reset the message to, if needed.header: Optional header information.
Example: Using a TwistPublisher
If you’re publishing velocity commands using the geometry_msgs/msg/Twist message type, you can use the simplified TwistPublisher class:
motor_commands = TwistPublisher(
rate=200,
input={"linear.x": neuron.velocity, "angular.z": neuron.angular},
)
Finally, register the publisher with the ROS device:
get_device().add_publisher(motor_commands)
This will start publishing data to the ROS network according to the specified rate and input values.
Subscriber
In ROS 2, a subscriber is a node component that listens to a specific topic and receives messages published by other nodes. When a message is received, a callback function is triggered to process the data — for example, to display it, control a simulation, or log the information.
As with publishers, creating a Subscriber with Brian2ROS is simple and intuitive. Just add the following line to your code:
Example: Basic Subscriber
range_sensor = Subscriber(
name="range",
topic="LaserScan",
topic_type="sensor_msgs/msg/LaserScan",
output={"ranges": [0]},
header=header
)
Parameters:
name: Internal name of the subscriber.topic: The name of the ROS topic to subscribe to.topic_type: Full ROS message type.output: Dictionary mapping fields from the ROS message to Brian variables.header: Optional header information
Example: LaserScanSubscriber
When subscribing specifically to a LaserScan message, you can use the simplified LaserScanSubscriber class:
range_sensor = LaserScanSubscriber(
name="range",
output={"ranges": 0}
)
This allows your Brian simulation to receive real-time sensor data and use it directly within your model.