There are two demo modes provided in this repository:
- demo_containerized/: Runs the entire simulation—including Gazebo—inside Docker containers. This is ideal for users who want a fully containerized, reproducible environment with minimal local setup.
- demo/: Runs Gazebo directly on the local machine, while the 5G Core Network and related services are still containerized. This mode is suitable for users who want to leverage their local Gazebo installation for better performance or direct GUI access.
Both demos support all three 5G Core Network options (OAI, free5GC, Open5GS). Choose the mode that best fits your workflow and system configuration.
This repository contains the model and the plugins, developed by phine.tech, to simulate the behaviour of a gNB and a UE in Gazebo Ignition. The plugins are compatible with three 5G Core Network implementations (OAI, free5GC, and Open5GS), all deployed as docker containers, making advanced 5G networking accessible to the robotic community. The aim is that a roboticist who is not an expert in 5G connectivity can easily simulate their robotic applications in a 5G end-to-end network without knowing the underlying technical details. Throughout this documentation, OAI (Open Air Interface) is used as an example, but the same concepts apply to all supported core networks.
The table of content of this README file is:
If something goes wrong in following this README file or you have any questions, you can write on our slack chat.
The project has been tested with:
-
Ubuntu 22.04
-
ROS2 humble
-
Docker version 27.5.1, build 9f9e405
-
Docker Compose version v2.33.1
-
gazebo ignition fortress 2.6.9
RoboSim5G supports multiple 5G Core Network implementations. You can choose the one that best fits your needs:
- OAI (OpenAirInterface) - High-performance, research-focused implementation
- free5GC - User-friendly with comprehensive WebUI for subscriber management
- Open5GS - Mature implementation with excellent documentation
📖 See doc/5G_CORE_NETWORKS.md for a detailed comparison and guidance on choosing the right core network.
Each core network has its own setup folder under core_network_setup/:
- OAI:
core_network_setup/oai/ - free5GC:
core_network_setup/free5gc/ - Open5GS:
core_network_setup/open5gs/
The following example uses OAI, but similar steps apply to other core networks.
Considering path the absolute path to the repository, the OAI core network files can be found in path/core_network_setup/oai. Inside this folder there is a docker-compose.yml for launching the OAI Core Network containers.
The gNB and UE docker-compose files are located in the demo folders under oai/:
-
demo/oai/docker-compose-gNB.ymlfor launching the OAI gNB container (used by all core networks, since the RAN components come from OAI v2026.w04) -
demo/oai/docker-compose-ue.ymlfor launching the OAI UE container (and also other containers related to the demo)
Other folders are present inside core_network_setup/oai, containing configuration files useful for these containers. It is possible to verify that the OAI modules work, by following this pipeline:
- In one terminal run the core network:
cd path/core_network_setup/oai
docker compose up -d
In the same terminal (wait 5-10 seconds):
docker logs oai-udr
If everything went correctly, in the logs you should see:
[2025-02-28 13:01:58.215] [udr_app] [debug] Instance name: OAI-UDR
[2025-02-28 13:01:58.215] [udr_app] [debug] Instance type: UDR
[2025-02-28 13:01:58.215] [udr_app] [debug] Instance fqdn:
[2025-02-28 13:01:58.215] [udr_app] [debug] Status: REGISTERED
[2025-02-28 13:01:58.215] [udr_app] [debug] HeartBeat timer: 50
[2025-02-28 13:01:58.215] [udr_app] [debug] Priority: 1
[2025-02-28 13:01:58.215] [udr_app] [debug] Capacity: 100
[2025-02-28 13:01:58.215] [udr_app] [debug] IPv4 Addr:
[2025-02-28 13:01:58.215] [udr_app] [debug] 192.168.70.136
[2025-02-28 13:01:58.215] [udr_app] [debug] UDR Info
[2025-02-28 13:01:58.215] [udr_app] [debug] GroupId: oai-udr-testgroupid
[2025-02-28 13:01:58.215] [udr_app] [debug] SupiRanges: Start - 208950000000131, End - , Pattern - ^imsi-20895[31-131]{6}$
[2025-02-28 13:01:58.215] [udr_app] [debug] GpsiRanges: Start - 752740000, End - 752749999, Pattern - ^gpsi-75274[0-9]{4}$
[2025-02-28 13:01:58.215] [udr_app] [debug] Data Set Id: 0210
[2025-02-28 13:01:58.215] [udr_app] [debug] Data Set Id: 9876
- in the same terminal run the gNB container (from the demo folder):
cd path/demo/oai
docker compose -f docker-compose-gNB.yml up -d
In the same terminal (wait 5-10 seconds):
docker logs oai-amf
If everything goes well you should see in the logs a table with the list of the connected gNBs and their names (in this case one named gnb-rfsim):
|------------------------------gNBs' Information-------------------------|
| Index | gNB Name | Status | PLMN | Global Id |
| 1 | gnb-rfsim | Connected | 001,01 | 0x0E00 |
-------------------------------------------------------------------------------
- in the same terminal run the UE container:
docker compose -f docker-compose-ue.yml up -d
In the same terminal(wait 5-10 seconds):
docker logs oai-amf
in the logs you will see if it is working:
|----------------------UEs' Information-----------------------------------------|
| Index | 5GMM State | IMSI | GUTI |
| 1 | 5GMM-REGISTERED | 001010000000101 |00101010041631377652|
RAN UE NGAP ID | AMF UE NGAP ID | PLMN | Cell Id
0x01 | 0x01 | 001,01 | 000000100 |
|----------------------------------------------------------------------------|
To stop and remove all the containers:
cd path/demo/oai
docker compose -f docker-compose-gNB.yml down
docker compose -f docker-compose-ue.yml down
cd path/core_network_setup/oai
docker compose down
This plugin allows rapid deployment and configuration of a 5G gNodeB (gNB) directly from a Gazebo SDF world file. It is designed to be attached to a simple visual model representing a 5G cell and provides dynamic runtime behavior and container-based backend automation.
The gNB is visually represented in Gazebo as a white, thin box, resembling a 5G antenna.
The model can be found at:
path/model_folder/phine_gNB/model.sdfNote: Gravity is disabled for this model to make its placement easier in the world.
-
Source location:
path/phine-gz-ros/src/phine_plugins/src -
Prebuilt plugin library:
path/phine-gz-ros/build/phine_plugins/libgNB-plugin.so
If you modify the source code, rebuild the plugin using:
cd path/phine-plugins && colcon buildSome warning messages may appear during the build — they can usually be ignored unless they block functionality.
-
Modifies configuration files for the gNB container:
-
docker-compose-gNB.yml -
gNB_config.yaml
Changes include:
-
Docker network name
-
gNB IP address
-
AMF IP address
-
-
Launches the gNB container
-
Optionally sends debug information
- Publishes the pose of the gNB to a ROS 2 topic called
/pose_of_<name_of_gNB>
Before launching the world, make sure the following environment variables are exported:
export PROJECT_PATH=<your-project-path> # Must contain oai/
export IGN_GAZEBO_SYSTEM_PLUGIN_PATH=<path-to-plugins> # Contains libgNB-plugin.so
export IGN_GAZEBO_RESOURCE_PATH=<path-to-models> # Contains phine_gNB model`Note: The world file is now automatically selected based on the CORE_NETWORK environment variable (defaults to oai). The launch file reads CORE_NETWORK and loads world_only_{core_network}.sdf — no manual editing of the launch file is needed.
Add the following to your world-file.sdf to include the gNB:
<include>
<uri>model://phine_gNB</uri>
<name>gNB1</name>
<pose>0 0 1 0 0 0</pose>
<plugin name="phine_plugins::gNB_plugin" filename="gNB_plugin">
<cn_type>oai</cn_type> <!-- Options: oai, free5gc, open5gs -->
<link_name>phine_cell</link_name>
<net_name>phine-net</net_name>
<IP_GNB>192.168.70.159</IP_GNB>
<IP_AMF>192.168.70.132</IP_AMF>
<debug>false</debug>
<mobile_country_code>001</mobile_country_code>
<mobile_network_code>01</mobile_network_code>
</plugin>
</include>| Parameter | Description |
|---|---|
cn_type |
Core Network type (oai, free5gc, or open5gs) |
name |
Name of the gNB instance (e.g., gNB1, gNB2, ...) gNB<N> format |
pose |
Pose of the gNB in the world (x y z roll pitch yaw) |
link_name |
Link whose pose is streamed over ROS 2 (keep as phine_cell unless model changes) |
net_name |
Name of the Docker network to attach the gNB container |
IP_GNB |
Static IP address of the gNB container |
IP_AMF |
IP address of the AMF container (Must match value in core_network_setup/oai/conf/config.yaml) |
debug |
Set to true to enable plugin debug output |
mobile_country_code |
MCC used for registration, must match value in AMF config |
mobile_network_code |
MNC used for registration, must match value in AMF config |
The idea is that, after declaring this plugin inside an SDF Gazebo world, the plugin launches a robot-UE container that contains both your robot logic and a UE process. This UE process continuously runs to emulate the presence of a 5G modem in your robot.
You will need to define the path to the launch file for your robot logic (such as its navigation stack), configure the 5G parameters, and the UE plugin will build the image and launch the container.
However, this plugin is tightly coupled to the system architecture designed by phine.tech, and it assumes the following structure:
-
robot-UE container:
Launched by the UE plugin. It runs:-
The 5G UE process (continuously running)
-
The robot logic (launch file provided by the user)
-
The
ros_gz_bridge(launch file provided by the user)
-
-
Remote Control Center (RCC) container:
Sends desired positions to the robot. -
Gazebo world:
Launched on the host machine. You must include the UE and gNB plugin definitions and models in the world file. -
DDS Discovery Server:
Required to enable ROS 2 discovery over the 5G network.
The robot-UE container must be able to route to the DDS server.
The IP and port of the DDS server are specified in the plugin configuration. -
5G Core Network:
Provided by OAI (OpenAirInterface).
To replicate this architecture, it is essential to divide your ROS 2 workspace logically. Robotics projects often use a single monolithic launch file, but in this case, it should be divided in:
-
Gazebo World Workspace
-
Launches the simulation world.
-
Includes:
-
World file
-
UE and gNB models
-
Plugin declarations
-
-
-
Robot Workspace
-
Includes two specific launch files used by the UE plugin:
-
Robot logic launch file: e.g., navigation, SLAM
-
ros_gz_bridge launch file: for ROS <-> Gazebo communication
-
-
-
Remote Control Workspace
-
Sends goal positions to the robot
-
Typically includes:
-
RViz launch file
-
RViz configuration file
-
routing trough upf or ext-dn to reach the UE (
ip route add <ue_ip_range> via <upf/ext_dn_ip> dev <interface>)
-
-
-
Discovery server
-
enable unicast communication(multicast not available in majority of CN)
-
needs routing trough upf or ext-dn to reach the UE (
ip route add <ue_ip_range> via <upf/ext_dn_ip> dev <interface>)
-
A good reference is path/demo/nav_stack folder that will be copied inside the robot-UE container for the demo.
Routing through the upf is necessary for any container in the Data network(outside 5G network).
The system relies on three main networks:
-
public_net-
Bridges all 5G network functions
-
Name and subnet can be customized
-
Must be referenced in the plugin configuration
-
-
ros_gz_net-
Mimics the physical layer between the robot PC and actuators
-
Directly connects the Gazebo host with the robot-UE container
-
Static IP: The robot container must always use
192.168.73.150 -
The subnet cannot be changed
-
-
5G network
-
Used for communication between the remote control center and the robot
-
Subnet is configurable in
path/core_network_setup/oai/conf/config.yaml
-
ROS 2 communication over 5G networks requires careful DDS (Data Distribution Service) configuration. The architecture uses Fast DDS profiles to control network transport behavior and enable proper discovery across the distributed system.
- Multicast not available: Most 5G Core Networks do not support multicast traffic, requiring unicast-only communication
- Interface selection: The UE must communicate exclusively through its 5G tunnel interface, not other network interfaces
- Fragmentation prevention: Large ROS 2 messages must be handled properly to avoid UDP fragmentation issues
- Discovery server: Centralized discovery is needed since multicast discovery won't work over 5G
The robot-UE container uses a restrictive profile that whitelists only the 5G tunnel interface (e.g., 10.0.0.x addresses). This ensures all ROS 2 traffic goes through the 5G network.
Key configuration (example from path/demo/images/ue_amr/dds.xml):
<transport_descriptor>
<transport_id>UDP_5G_Only</transport_id>
<type>UDPv4</type>
<maxMessageSize>1400</maxMessageSize> <!-- Fragmentation prevention -->
<sendBufferSize>1048576</sendBufferSize>
<receiveBufferSize>1048576</receiveBufferSize>
<non_blocking_send>true</non_blocking_send>
<interfaceWhiteList>
<address>10.0.0.1</address>
<address>10.0.0.2</address>
<!-- ... additional 5G tunnel addresses ... -->
</interfaceWhiteList>
</transport_descriptor>
<participant profile_name="Participant_5G_Only" is_default_profile="true">
<rtps>
<userTransports>
<transport_id>UDP_5G_Only</transport_id>
</userTransports>
<useBuiltinTransports>false</useBuiltinTransports> <!-- Disable default transports -->
<builtin>
<avoid_builtin_multicast>true</avoid_builtin_multicast> <!-- Force unicast -->
</builtin>
</rtps>
</participant>Important aspects:
maxMessageSize: Set to 1400 bytes to prevent UDP fragmentationinterfaceWhiteList: Restricts communication to 5G tunnel addresses onlyuseBuiltinTransports: false: Disables default DDS transportsavoid_builtin_multicast: true: Forces unicast-only communication
Nodes in the Data Network (like the Remote Control Center) use a SUPER_CLIENT profile to connect to the centralized Discovery Server.
Key configuration (example from path/demo/images/rcc/dds.xml):
<participant profile_name="participant_profile_client_full_example" is_default_profile="true">
<rtps>
<builtin>
<discovery_config>
<discoveryProtocol>CLIENT</discoveryProtocol> <!-- Client mode -->
<discoveryServersList>
<RemoteServer prefix="44.53.00.5f.45.50.52.4f.53.49.4d.41">
<metatrafficUnicastLocatorList>
<locator>
<udpv4>
<address>192.168.70.159</address> <!-- Discovery server IP -->
<port>11811</port> <!-- Discovery server port -->
</udpv4>
</locator>
</metatrafficUnicastLocatorList>
</RemoteServer>
</discoveryServersList>
</discovery_config>
</builtin>
</rtps>
</participant>Important aspects:
discoveryProtocol: CLIENT: Uses centralized discovery instead of multicastdiscoveryServersList: Points to the Discovery Server's IP and port- Unicast locators: All discovery traffic uses unicast UDP
The Discovery Server itself must be configured with the SERVER or SUPER_SERVER profile and must be reachable from both:
- The UE containers (via 5G tunnel with routing through UPF)
- The Data Network containers (via
public_net)
Environment variable to enable discovery server mode:
export ROS_DISCOVERY_SERVER=<discovery_server_ip>:11811The Discovery Server IP must match the value in both the UE plugin <ros_discovery_server> parameter and the DDS profiles.
When the plugin is loaded, it performs the following steps:
-
Modifies configuration files for the UE in
$PROJECT_PATH/oai, specifically:-
docker-compose-ue.yml -
oai/conf/UE_config.yaml
-
-
Copies the user robot workspace inside the
$PROJECT_PATH/images/ue_amrfolder, which should contain:-
robot logic launch file
-
ros_gz_bridge launch file
-
-
Builds the
ue-amrDocker image, which contains:-
A continuously running 5G UE process
-
The robot logic (user-defined launch file)
-
The
ros_gz_bridge
-
-
Launches the robot-UE container, using the
robot_<robot_ID>service defined in$PROJECT_PATH/oai/docker-compose-ue.yml
(Currently, only<robot_ID>=1is tested.) -
Automatically launches the ROS-Gazebo bridge inside the container
-
Automatically launches the robot logic, unless this feature is disabled via the
execute_robot_launch_fileoption in the plugin SDF -
Sends debug information, if requested
Set the following environment variables on the host system:
export PROJECT_PATH=<your-project-path> # Must contain oai/
export IGN_GAZEBO_SYSTEM_PLUGIN_PATH=<path-to-plugins> # Contains libUE-plugin.so and libgNB-plugin.so
export IGN_GAZEBO_RESOURCE_PATH=<path-to-models> # Contains phine-gNB model
export ROS_DOMAIN_ID=<your-ros2-domain-id> # Shared by host and robot-UE container
export IGN_PARTITION=<your-ign-partition> # Shared by host and robot-UE container
export IGN_TRANSPORT_INTERFACE=192.168.73.129 # Used for direct Gazebo <-> robot-UE link`You also must add a route to the 5G network via the UPF (User Plane Function) node, using:
sudo ip route add <5G_subnet> via <ip_upf> dev <public_net_interface>This command ensures that traffic destined for the 5G subnet is routed correctly to the robot.
If you are launching your Gazebo world via a ROS 2 launch file:
-
Include the
phine-gNBmodel frompath/model_folder/phine_gNBand make sure the path is listed inIGN_GAZEBO_RESOURCE_PATH. -
Add the following plugin to your
IGN_GAZEBO_SYSTEM_PLUGIN_PATH:-
path/phine-gz-ros/build/phine_plugins/libUE-plugin.so -
path/phine-gz-ros/build/phine_plugins/libgNB-plugin.so
-
When loading a complex world with physical models and the UE plugin, Gazebo may fail to open.
Workaround:
Create a single composite model that includes all the physical objects in the world, and declare all plugins at the world level.
Refer to path/demo/gazebo_launch for an example.
-
The plugin expects the folder:
$PROJECT_PATH/oai/images/ue_amr
It must contain the files from:
path/demo/images/ue_amr -
This directory must contain a
Dockerfileused to build theue_amrimage.
You can customize the Dockerfile to install additional robot dependencies or ROS packages. -
The folder
$PROJECT_PATH/oaimust also contain:-
All configuration files for the 5G OAI components
-
Compose files to launch the core network, gNB, and UE(s)
Specifically, the plugin will launch the
robot_<robot_ID>service defined in:
$PROJECT_PATH/oai/docker-compose-ue.ymlYou may extend
docker-compose-ue.ymlto include services for:-
The DDS Discovery Server
-
The Remote Controller (e.g., RViz node for navigation goals)
It’s recommended to reuse the demo service definitions.
-
-
The robot container must join two networks:
-
public_net -
ros_gz_net— with static IP192.168.73.150(this IP must not change)
-
-
UE plugin source code is located in:
path/phine-plugins/src/phine_plugins/src -
The compiled
.sois already available at:
path/phine-gz-ros/build/phine_plugins/libUE-plugin.so -
If you modify the plugin source code, rebuild the
phine_pluginsROS 2 package:
cd path/phine-plugins colcon buildSome warning messages may appear — these can usually be ignored unless they affect functionality.
The majority of parameters for the UE plugin are tailored to the framework demonstrated in the provided path/demo. If you plan to adapt this plugin for your own application, you should first understand the structure and logic of the demo, and maintain a similar organization in your project.
To add the UE plugin to your SDF world file, include:
<plugin name="phine_plugins::UE_plugin" filename="UE_plugin">
<cn_type>oai</cn_type> <!-- Options: oai, free5gc, open5gs -->
<robot_container_name>ue_turtlebot</robot_container_name>
<robot_id>1</robot_id>
<ip_robotUE>192.168.70.150</ip_robotUE>
<net_name>phine-net</net_name>
<ip_gnb>192.168.70.160</ip_gnb>
<debug>true</debug>
<subnet_5G>10.0.0.0/28</subnet_5G>
<imsi>001010000000101</imsi>
<key>fec86ba6eb707ed08905757b1bb44b8f</key>
<opc>C42449363BBAD02B66D16BC975D77CC1</opc>
<dnn>oai</dnn>
<nssai_sst>1</nssai_sst>
<robot_project_path>${PROJECT_PATH}/nav_stack</robot_project_path>
<robot_project_name>nav_stack</robot_project_name>
<execute_robot_launch_file>true</execute_robot_launch_file>
<robot_package_name>ign_turtlebot</robot_package_name>
<ros_gz_bridge_name>ros_gz_bridge.launch.py</ros_gz_bridge_name>
<robot_launch_file_name>nav_stack.launch.py</robot_launch_file_name>
<ros_discovery_server>192.168.70.159:11811</ros_discovery_server>
</plugin>| Parameter | Description |
|---|---|
cn_type |
Core Network type (oai, free5gc, or open5gs) |
robot_container_name |
Name of the UE container to be launched (e.g., ue_turtlebot) |
robot_id |
Unique ID for the robot |
ip_robotUE |
Static IP assigned to the robot UE container |
net_name |
Name of the Docker network to attach the UE container |
ip_gnb |
IP address of the gNB container |
debug |
If true, plugin will print debug logs |
subnet_5G |
Subnet of the 5G network (must match core config, e.g., 10.0.0.0/16) |
imsi |
Unique identifier for the UE (matches entry in core network config) |
key |
128-bit cryptographic key shared with 5G core for authentication |
opc |
Operator-specific key used in authentication |
dnn |
Data network name (e.g., oai, internet, ims) |
nssai_sst |
Network slice type (e.g., 1 for eMBB, URLLC, etc.) |
nssai_sd |
Slice differentiator. Optional (defaults to no); if omitted or no, not written to UE config |
robot_project_path |
Path to the ROS 2 workspace with robot logic |
robot_project_name |
Name of the ROS 2 workspace with robot logic |
execute_robot_launch_file |
Whether to launch robot logic inside the container (true or false) |
robot_package_name |
ROS 2 package name containing the robot's launch files |
ros_gz_bridge_name |
Name of the launch file for the ROS-Gazebo bridge |
robot_launch_file_name |
ROS 2 launch file for robot logic (e.g., navigation) |
ros_discovery_server |
IP and port of the Fast DDS discovery server (e.g., 192.168.70.159:11811) |
-
UE credential files are located in:
path/demo/oai/conf/UE_config.yaml -
All credentials (
imsi,key,opc,dnn,nssai_sst,nssai_sd) must match the configuration of the 5G core network. -
The
nssai_sdparameter is optional (defaults to"no"). If omitted or set to"no", it won't be written to the UE config. -
The
<subnet_5G>must match the value defined in the core network's configuration file:
path/core_network_setup/oai/conf/config.yaml- Be sure to follow the same network and workspace structure as the demo for compatibility.
The Network Monitor is an Ignition Gazebo GUI plugin that provides real-time measurement of latency and bandwidth over the simulated 5G link between a User Equipment (UE) container and the Data Network (DN) container. It uses ping for latency and iperf3 for bandwidth, executed via docker exec on the respective containers.
In any ROS 2 robotic application, the communication layer has a direct impact on system performance and safety. ROS 2 relies on DDS (Data Distribution Service) for all inter-node communication — including publishing sensor data, sending navigation goals, and exchanging control commands. When this communication happens over a 5G network instead of a local Ethernet or Wi-Fi link, the characteristics of that network become a critical factor:
-
Latency affects control loops. ROS 2 navigation stacks (e.g., Nav2) and teleoperation nodes depend on timely delivery of odometry, laser scans, and velocity commands. A latency spike over the 5G link can cause the robot to overshoot a waypoint, react late to an obstacle, or lose localization. Knowing the real-time round-trip time helps you understand whether your control loop frequency is achievable.
-
Bandwidth affects data-heavy topics. Point clouds, camera images, and map updates are large messages. If the 5G uplink or downlink bandwidth is insufficient, DDS will drop messages or queue them, leading to stale data at the subscriber side. Monitoring bandwidth lets you verify that the 5G link can sustain the throughput your application requires.
-
5G behavior is not static. Unlike a wired connection, a 5G link is subject to variability due to radio scheduling, handovers, and shared spectrum. Having a live monitor during simulation lets you correlate network conditions with robot behavior — for example, observing that navigation failures coincide with a bandwidth drop.
-
Validation before field deployment. RoboSim5G is designed to let roboticists test their applications over a realistic 5G stack before deploying on physical hardware. The Network Monitor closes the loop: you can verify that the network performance meets the requirements of your ROS 2 application (e.g., < 50 ms RTT for teleoperation, > 10 Mbits/sec for video streaming) entirely within the simulation.
In short, if you are running ROS 2 topics over a 5G network, you should monitor that network — the Network Monitor plugin gives you that visibility directly inside Gazebo.
Once started, the plugin:
- Launches an iperf3 server in daemon mode on the UE container.
- Enters a continuous measurement loop that performs, in each cycle:
- Downlink latency:
pingfrom the DN container to the UE IP (1 packet, 1 s timeout). - Uplink latency:
pingfrom the UE container to the DN IP (1 packet, 1 s timeout). - Downlink bandwidth:
iperf3from the DN client to the UE server (1 s test). - Uplink bandwidth:
iperf3in reverse mode (-Rflag) (1 s test).
- Downlink latency:
- Updates the GUI with the latest results after each cycle.
- When stopped, kills the iperf3 server on the UE container.
Each measurement cycle takes approximately 4 seconds, keeping the overhead low enough to avoid slowing down the simulation.
The Network Monitor is a GUI plugin that can be added to your Gazebo Ignition world file or loaded at runtime from the Gazebo GUI plugin menu.
Add the following block inside the <gui> section of your world file:
<gui>
<plugin name="phine_plugins::NetworkMonitor" filename="NetworkMonitor">
<ue_ip>10.0.0.1</ue_ip>
<dn_ip>192.168.70.135</dn_ip>
<ue_container_name>ue_turtlebot</ue_container_name>
<dn_container_name>oai-ext-dn</dn_container_name>
</plugin>
</gui>All parameters are optional — they can also be set at runtime from the GUI text fields.
The UE container name can also be set via the UE_NAME_FOR_BUTTON environment variable:
export UE_NAME_FOR_BUTTON=ue_turtlebotIf set, it overrides the default value (ue_turtlebot). A value provided in the SDF <ue_container_name> element takes precedence over the environment variable.
Once the plugin is loaded in Gazebo:
- Enter the UE IP (the 5G tunnel IP assigned to the UE, e.g.,
10.0.0.1) and the DN IP (the Data Network container IP, e.g.,192.168.70.135). - Click Start Test to begin continuous monitoring.
- The panel displays live uplink/downlink latency and bandwidth.
- Click Stop Test to end the measurement loop.
| Parameter | Description | Default |
|---|---|---|
ue_ip |
5G tunnel IP of the UE (e.g., 10.0.0.1). Can be set from the GUI at runtime. |
(empty) |
dn_ip |
IP of the Data Network container (e.g., 192.168.70.135). Can be set from GUI. |
(empty) |
ue_container_name |
Docker container name of the UE | ue_turtlebot |
dn_container_name |
Docker container name of the Data Network node | oai-ext-dn |
- iperf3 must be installed inside both the UE and DN containers.
- ping must be available inside both containers.
- The Gazebo host must have Docker access (the plugin runs
docker execcommands). - The plugin shared library (
libNetworkMonitor.so) must be in a path listed inIGN_GAZEBO_GUI_PLUGIN_PATH.
The gNB Power Plugin and UE Power Plugin are Ignition Gazebo GUI plugins that provide runtime control over the 5G radio processes (gNB and UE softmodems) running inside Docker containers. These plugins allow you to start, stop, and monitor the OAI radio software directly from the Gazebo GUI without needing to manually execute Docker commands.
Both plugins provide a graphical interface to:
- 🟢 Start/Stop the radio process (
nr-softmodemfor gNB,nr-uesoftmodemfor UE) inside the container - � Monitor process state (running/stopped) with visual indicators
- 🔧 Configure runtime parameters like container names and IP addresses
This is particularly useful during simulation development and testing, where you may need to:
- Verify 5G connectivity by restarting the UE or gNB
- Test failure scenarios by stopping the radio link
- Observe how your robot application handles connection loss
- First Click (Connect): Checks if the
nr-softmodemprocess is running in the specified gNB container - Subsequent Clicks (Toggle): Starts or stops the gNB radio process using
.yamlconfiguration (no--saflag)
Works similarly to the gNB plugin, but controls the nr-uesoftmodem process in the UE container:
- Uses
.yamlfile with frequency3319680000Hz - Requires the gNB IP address to establish the RF simulator connection
Both plugins are GUI plugins that can be added to your Gazebo Ignition world file or loaded at runtime from the Gazebo GUI plugin menu.
Add the following blocks inside the <gui> section of your world file:
<gui>
<plugin name="phine_plugins::gNBPowerPlugin" filename="gNBPowerPlugin">
<container_name>oai-gNB1</container_name>
</plugin>
</gui><gui>
<plugin name="phine_plugins::UePowerPlugin" filename="UePowerPlugin">
<container_name>ue_turtlebot</container_name>
<gnb_ip>192.168.70.160</gnb_ip>
</plugin>
</gui>All parameters are optional and can be configured at runtime from the GUI.
The UE container name can be set via the UE_NAME_FOR_BUTTON environment variable:
export UE_NAME_FOR_BUTTON=ue_turtlebotIf set, this overrides the default value. A value provided in the SDF <container_name> element takes precedence.
When loaded, the plugin displays:
- Container Name Field: Name of the gNB Docker container (e.g.,
oai-gNB1) - Power Button:
- First click: Connect to the container and check process status
- Subsequent clicks: Toggle the gNB process on/off
- Color indicators: 🟢 Green (running) / 🔴 Red (stopped)
- Status Display: Shows current connection and process state
Similar to gNB, with an additional field:
- Container Name Field: Name of the UE Docker container (e.g.,
ue_turtlebot) - gNB IP Field: IP address of the gNB for RF simulator connection (e.g.,
192.168.70.160) - Power Button: Connect and toggle the UE process
- Status Display: Connection and process state
Note: Container name and gNB IP can only be changed before the first connection. Once connected, these fields are locked to prevent accidental misconfiguration during active radio sessions.
| Parameter | Description | Default |
|---|---|---|
container_name |
Docker container name of the gNB | oai-gNB1 |
| Parameter | Description | Default |
|---|---|---|
container_name |
Docker container name of the UE | ue_turtlebot |
gnb_ip |
IP address of the gNB container for RF simulator | 192.168.70.160 |
These plugins have been tested and verified with:
- OAI 5G Core Network
- demo mode (Gazebo on host)
- demo_containerized mode (Gazebo in Docker)
Support for free5GC and Open5GS core networks is planned for future releases.
-
Launch your OAI 5G core network:
cd path/core_network_setup/oai docker compose up -d -
Launch gNB and UE containers (without starting the radio processes):
cd path/demo/oai docker compose -f docker-compose-gNB.yml up -d docker compose -f docker-compose-ue.yml up -d -
Start Gazebo with your world file that includes the power plugins
-
In Gazebo GUI:
- Open the gNB Power Control panel
- Verify container name
- Click Connect to check status
- Click Power Toggle to start the gNB radio
-
Then control the UE:
- Open the UE Power Control panel
- Verify container name and gNB IP
- Click Connect to check status
- Click Power Toggle to start the UE and establish the 5G connection
-
Monitor AMF logs to verify successful registration:
docker logs oai-amf
You should see the UE appear in the AMF's registered UEs table.
The source code of the plugins is at path/phine-plugins/src/phine_plugins/src. You can modify it as you wish consulting Coding Guidelines and Contributing and in case you would like to share your work. Once you have modified the code, delete path/phine-plugins/log,path/phine-plugins/install,path/phine-plugins/build and run in path/phine-plugins(with path the path to main folder of the repo):
colcon build
The updated plugins will be in path/phine-plugins/build.
