Skip to content

The Maveric project is the source of the RIC Algorithm Development Platform (RADP). It enables the development and evaluation of dynamic control policies that optimize cellular network operation, before their deployment on the network.

License

41vin/maveric

 
 

Repository files navigation

RIC Algorithm Development Platform (RADP)

The Maveric project is the source of the RIC Algorithm Development Platform (RADP). It enables the development and evaluation of dynamic control policies that optimize cellular network operation, before their deployment on the network. It is intended to serve the use-case of developing solutions that leverage the Radio Intelligent Controller (RIC) paradigm. It is a developer platform that leverages AI/ML approaches to provide realistic cellular network representations (known as digital twins), as well as examples of simple xApp/rApp algorithms, that demonstrate its use.

Table of Contents

Development Workflow

Please follow the development workflow here when making code changes.

Getting Started

Downloading the repo

If you haven't already, download or clone this repo on the machine where you'd like to run RADP.

Installing and running Docker

To run the RADP service you will need to install Docker.

Once Docker is installed make sure to start the docker daemon.

Booting up RADP

Once Docker is running you just need to cd to the "radp" directory (if you're not already there) and run the following command

docker build -t radp radp

[Alternative] Using GPUs from host

Docker has native support for this.

Host must have Nvidia driver, Nvidia Container toolkit installed.

RADP Docker Compose files are already set to attach Nvidia GPUs if available.

You will need to specify a different base image for Docker Compose:

docker build -f radp/Dockerfile-cuda -t radp radp

Then you can start RADP in production mode:

docker compose -f dc.yml -f dc-prod.yml up -d --build

Or with Nvidia GPU support too:

docker compose -f dc.yml -f dc-prod.yml -f dc-cuda.yml up -d --build

This will do the following:

  1. Build the docker images using their local Docker files
  2. Calls docker run to build containers for each service
  3. Creates services, volumes, kafka topics, and other components of RADP architecture

The first time you run this command it may take a while since Docker will need to download container images. You'll see a lot of text appear on your terminal.

Once you can see the RADP API service expose a web address you'll know you're ready to call the system's APIs:

radp-init               | Successfully created the following topics:
radp-init               | jobs
radp-init               | outputs
radp-init exited with code 0

Installing Python client dependencies

RADP currently requires Python >= 3.8.x and < 3.11.x

The last remaining holdout to support Python 3.11 appears to be the Torch library, which should be resolved soon.

CD to the top level of the repo. Run the following command to install Python client dependencies:

python3 -m venv .venv
source .venv/bin/activate
pip3 install --upgrade pip
pip3 install -r radp/client/requirements.txt

Running an example simulation

Install example requirements:

pip3 install -r apps/requirements.txt

You can copy the sample Environment files and make changes to them if desired:

copy .env-prod .env

This package comes with an example script which you can call to see the RADP service in action:

python3 apps/example/example_app.py

If the simulation runs end-to-end successfully, you should see an outputted dataframe containing the example simulation output.

Likewise, a basic Coverage and Capacity Optimization (CCO) example can be run as follows:

python3 apps/coverage_capacity_optimization/cco_example_app.py

The app takes about 2 minutes to run and produce final results on the console.

Stopping the RADP System

To stop the services run:

docker compose -f dc.yml -f dc-prod.yml down

in a terminal tab.

If you encounter an error here or hit ctrl + c you may kill your containers, possibly leaving them or their volumes in an unhealthy state. To clean your Docker containers and volumes, just run the following commands.

  1. docker container prune to remove stopped containers
  2. docker volume prune to remove unused volumes

IMPORTANT: Running volume prune will completely remove your RADP system data so only run during development


Train API

The Train API allows a user to train a new RF Digital Twin model.

    radp_client.train(
        model_id=model_id,
        params={},
        ue_training_data="ue_training_data.csv",
        topology="topology.csv",
    )
  • model_id (str, required) - the model_id which will be used to reference this model in subsequent calls to the Simulation API.
  • params (dict, required) - the training parameters to pass in for training, see Training Params
  • ue_training_data (str or pandas dataframe object, required) - the file path of the UE Training Data File (or a training data pandas dataframe)
  • topology (str or pandas dataframe object, required) - the file path of the cell Topology File (or a cell topology pandas dataframe), required to enable the model to preprocess the UE training data and create per-cell engineered features for training

See the example_app.py script for an example where pandas dataframes are provided directly to the client.

Training Params

The following object shows all training params that can be specified.

{
    "maxiter": 100
    "lr": 0.05
    "stopping_threshold": 0.0001
}
  • maxiter (int, optional) - the max number of iterations to run in training
  • lr (float, optional) - model learning rate
  • stopping_threshold (float, optional) - stopping threshold for training

UE Training Data File

The UE training data file must be a CSV file with the following format:

cell_id avg_rsrp lon lat cell_el_deg
cell_1 -80 139.699058 35.644327 0
cell_1 -70 139.707889 35.647814 3
cell_1 -75 139.700024 35.643857 6
... ... ... ... ...
  • cell_id (str, required) - the ID of the cell unit, the RF Digital Twin will run training/inference on a per-cell unit basis
  • avg_rsrp (float, required) - the RSRP value for this cell, for the lon-lat pixel of data, this is the target value for supervised learning employed by the RF Digital Twin model
  • lon (float, required) - the longitude of this pixel of data
  • lat (float, required) - the latitude of this pixel of data
  • cell_el_deg (float, required) - the electrical antenna tilt of the cell

For an example of a UE training data file, see apps/example/ue_training_data.csv

Topology File

The topology file must be a CSV file with the following format:

cell_id cell_name cell_lat cell_lon cell_az_deg cell_carrier_freq_mhz
cell_1 Cell1 35.690556 139.691944 0 2100
cell_2 Cell2 35.690556 139.691944 120 2100
cell_3 Cell3 35.690556 139.691944 240 2100
... ... ... ... ... ...
  • cell_id (str) - the cell identfier
  • cell_name (str) - the name of the cell (optional)
  • cell_lat (float) - the cell latitude
  • cell_lon (str) - the cell longitute
  • cell_az_deg (int) - the cell azimuth degree
  • cell_carrier_freq_mhz (int) - the cell carrier frequency layer

For an example of a topology file, see apps/example/topology.csv


Simulation API

The Simulation API allows a user to run a RIC Simulation event. If called with a valid request, the simulation API will create a simulation event which can be described by calling the Describe Simulation API. Once the simulation has finished, the outputted results can be consumed by calling the Consume Simulation Output API

radp_client.simulation(
    simulation_event=simulation_event,
    ue_data=prediction_data,
    config=prediction_config,
)
  • simulation_event - the simulation event object
  • ue_data - the file path of the UE Data file, see Passing in UE Tracks via UE Data File; this can also instead by a pandas dataframe
  • config - the file path of the Cell Config file, see

Simulation Event Object

{
    "simulation_time_interval_seconds": 0.01,
    "ue_tracks": <UE Tracks object>,
    "rf_prediction": <RF Prediction Object>,
}
  • simulation_time_interval_seconds (float) - the simulation time interval in seconds; the time between "ticks" within the simulation - the above example would be 10ms between each tick
  • ue_tracks - the UE Tracks component to the simulation, see UE Tracks
  • rf_prediction - the RF Prediction component to the simulation, see RF Prediction

Cell Config File

cell_id cell_el_deg
cell_1 10
cell_2 10
cell_3 12
  • cell_id (str, required) - the cell identifier
  • cell_el_deg (float, required) - the electrical antenna tilt of the cell

Simulation API Output

{
    "simulation_id": 'c88e347c613d1727a1c6ce5b61bc0877'
}
  • simulation_id - the simulation identifier used to describe or consume output from this simulation

Describe Model API

The Describe Model API allows a user to describe the training status of a digital twin model. This allows the user to see if a model has finished training (and thus is ready to be used in simulation).

radp_client.describe_model(model_id)
  • model_id - the identifier of the model to describe

TO BE COMPLETED


Describe Simulation API

The Describe Simulation API allows a user to describe an existing simulation. The response will signal to the user whether the simulation has finished (and thus whether output results can be consumed).

radp_client.describe_simulation(simulation_id)
  • simulation_id - the identifier of the simulation to describe

TO BE COMPLETED


Consume Simulation Output API

The Consume Simulation Output API allows a user to consume the output data from a simulation. The API returns a pandas dataframe object pertaining to simulation output

Example:

rf_dataframe = radp_client.consume_simulation_output(simulation_id)
  • simulation_id (str, required) - the ID for the simulation

UE Tracks

UE track data must be either passed in or generated to run a RIC simulation. The ue_tracks key must be present in a SimulationEvent object.

Passing in UE Tracks via UE Data File

Users have the option of passing in their own UE track data to the simulation. To specify that you will pass UE Track data to a simulation you must include the ue_data_id key in the ue_tracks like the following:

"ue_tracks": {
    "ue_data_id": "ue_data_1"
},

The value provided will be used to identify this UE data passed in. It does not need to be the name of the file.

IMPORTANT: If two sequential calls to the simulation API contain the same value for this field, the RADP system will assume the provided UE tracks data is the same. The system caches data using a hash of this value. If you wish to pass and run a RIC simulation on a different data set you MUST change the value provided here.

Along with adding the ue_data_id key to the simulation object, the user must also pass the file path of the UE data to the RADP Client. See the example.py script for an example API call with UE data file path passed in. The UE data file must be a comma-separated csv file with the following case-sensitive columns. See ue_data.csv for an example.

mock_ue_id lon lat tick cell_id
1 139.699058 35.644327 0 1
2 139.707889 35.647814 0 1
3 139.700024 35.643857 0 1
1 139.699061 35.644322 1 2
2 139.707899 35.647813 1 2
... ... ... ... ...
  • lon (float) - the longitude of the pixel
  • lat (float) - the latitude of the pixel
  • mock_ue_id (str, optional) - a fake user equipment ID to associate with this pixel of data
  • tick (int, optional) - the relative index of this position with respect to time; if a a certain mock_ue_id has a position (x1,y1) at tick=1, then has position (x2, y2) at tick=2, the simulation sees that this UE has moved from (x1,y1) to (x2,y2) across an interval of time equal to simulation_time_interval_seconds
  • cell_id (str, optional) - the identifier of the cell to attach this data point to. If this column is present then RF prediction will only occur from this pixel to this cell. If this column is not provided then RF prediction will occur on a per-cell basis where RX power is outputted for this pixel for every cell in the topology

For an example of a UE Tracks data file, see apps/example/ue_data.csv

Generating UE Tracks

Users also have the option of generating UE tracks data using RADP's built-in UE Tracks Generation service. The service employs a gaussian markov-based mobility model to generate UE tracks data.

To include UE Tracks Generation in a RIC simulation, set up your UE tracks object as follows:

"ue_tracks": {
    "ue_tracks_generation" : {
        "ue_class_distribution": UEClassDistribution,
        "lat_lon_boundaries": LatLonBoundaries,
        "gauss_markov_params": GaussianMarkovParams,
    }
},

UEClassDistribution

This object specifies the distribution of UE classes as well as mobility parameters for each class. The following UE classes are supported (case-sensitive): - stationary - pedestrian - cyclist - car

To include a UE class in the generated UE tracks data, include the class as a key in the UETypes object, with a value of UEType. See below example which includes only pedestrians and cars:

"ue_class_distribution": {
    "pedestrian": UEClassParams,
    "car": UEClassParams,
},

UEClassParams

The basic parameters of the UE Class

  • count (int) - the number of UEs of this class to generate in the simulation
  • velocity (float) - the average velocity of this UE class (float in meters/second)
  • velocity_variance (float) - the average variance from the average velocity of this UE class (float)

An example UEClassDistribution with UEClassParams for pedestrian and car:

"ue_class_distribution": {
    "pedestrian": {
        "count": 5,
        "velocity": 1,
        "velocity_variance": 1
    },
    "car": {
        "count": 5,
        "velocity": 10,
        "velocity_variance": 0.5
    }
},

LatLonBoundaries

The latitude and longitude boundaries of the grid where the UE Tracks data will be generated. UE device tracks will not stray outside of these boundaries. See the following example:

"lat_lon_boundaries": {
    "min_lat": -90,
    "max_lat": 90,
    "min_lon": -180,
    "max_lon": 180
},

GaussianMarkovParams

This object specifies the Gauss-Markov parameters to tune the randomness of the generated UEs. The params that can be specified are:

  • alpha (float) - the tuning parameter used to vary the randomness. Totally random values are obtained by setting it to 0 and linear motion is obtained by setting it to 1
  • variance (float) - the randomness variance for the UEs
  • rng_seed (int) - the random generator seed to be used to generate the UE data. The seed is set manually for reproducibility

Below is an example of UE mobility generated using the UE Tracks Generation service.

Trajectory of 3 UEs for 25 ticks


RF Prediction

As a component of a RIC Simulation, users can specify a previously trained RF Digital Twin model to run RF Prediction.

Input to RF Prediction

The input to RF prediction is a data set pertaining to UE Tracks, thus to run RF Prediction UE Tracks must first be specified in the SimulationEvent object. The only field required to run RF Prediction is the ID of the trained Digital Twin model to use in RF Prediction.

"rf_prediction": {
    "model_id": "my_trained_digital_twin_1"
}

Output from RSRP

As output, the RF Prediction step will add predicted per-cell RX Power data to the UE Tracks data.

cell_id rxpower_dbm mock_ue_id lon lat tick
cell_1 -73.58406342082407 0 -22.647772018547954 59.7818913169958 0
cell_1 -73.58406342082407 1 119.78045195037765 54.86740569575272 0
cell_1 -73.58406342082407 2 72.1170723329875 -20.22066321601217 0
cell_1 -73.58406342082407 0 -23.17652796675165 59.49811644458839 1
cell_1 -73.58406342082407 1 121.23118177561184 55.20488171003581 1
cell_1 -73.58406342082407 2 70.39142709656107 -21.780123291101106 1
cell_1 -73.58406342082407 0 -27.928272856142712 60.77581594854604 2
cell_1 -73.58406342082407 1 126.61098550003226 58.21946030130971 2
cell_1 -73.58406342082407 2 69.80139485065422 -21.980885049368638 2
  • cell_id (str) - the ID of the cell for which this RF prediction is made
  • rxpower_dbm (float) - the predicted RSRP value (in dBm) for this cell, for the lat-lon position specified

RADP Service Limitations

This section lays out the known limitations of the service.

Job Lengths

Below are the timeout thresholds for training and simulation jobs

  • training - 12 hours
  • simulation - 15 minutes for each stage in a simulation event

To explain, a training job can take up to 12 hours after which it will timeout. A simulation event can handle as much data as is possible without passing a 15 minute length of time for any single stage in the simulation pipeline. The developer team plans to implement batch processing, after which this will no longer be a limitation.

Something wrong?

For all of these API's you should be able to see relevant output in your terminal tab in which you ran docker compose. If you see error outputs for any command then something is wrong!

Running Notebooks

Please follow this guide for running notebooks.

LICENSE

See license

About

The Maveric project is the source of the RIC Algorithm Development Platform (RADP). It enables the development and evaluation of dynamic control policies that optimize cellular network operation, before their deployment on the network.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • Python 80.7%
  • Jupyter Notebook 18.4%
  • Other 0.9%