Skip to content. | Skip to navigation

Personal tools


You are here: Home / Wiki / PhantomNet / Motion modeling with PhantomNet attenuator matrix

Motion modeling with PhantomNet attenuator matrix

Attenuator Code for Diverse Motion Modeling

Mark Van der Merwe

Report on internship project



The PhantomNet project is dependent upon being able to create realistic motion models for the UE to follow. By creating these realistic models, we allow the user to test their applications during handover in ways more realistic to the outside world, while still maintaining the repeatable factor. In this way, PhantomNet can become a valuable asset to the mobile networking research community.

PhantomNet is designed to use attenuator boxes to simulate movement. By using these programmable attenuators, the system can accurately and repeatedly simulate movement.

The code documented here attempts to create three options which will allow people to easily test their applications on PhantomNet in several different ways. The options are:

  1. Testing individual attenuation points in a step-wise manner,
  2. Linear interpolation of attenuation points to create a more smooth realistic playback of recorded attenuations,
  3. Input of geometric locations for the UE rather than attenuations.

We believe these three options are a good start for creating useful motion modelling functions in PhantomNet.

Earlier versions of our work involved basic setting of attenuator values and learning the functionality of the attenuator device. Our early work also allowed us to test whether or not the attenuators behaved as expected. Our results were positive, though we are currently waiting for further equipment before more precise and accurate testing can take place.


The code I developed was creating using Expect script, based on tcl. Expect allows us to automate interactive applications. We used its functionality to be able to enter commands into a command line to our attenuator. Expect gives us a lot of room to be smart and develop an interactive, smooth-working product.

Our code is designed to be run from an Emulab machine. This machine is connected through the Emulab network to the attenuator (via ethernet). SSH into the machine and you are ready to go. The code to start an Expect script is expect followed by the name of the file. For example to run this program we say: expect attenArray.exp. Note also that if you update the code in any way (change the attenuations, timestamps, heights, etc.) you will need to scp (secure copy) the file to the Emulab machine you are working on.

The attenuator used in our evaluation is a JFW MODEL 50BA-002-95 Benchtop Programmable Attenuator made by JFW Industries, Inc. It has two attenuators in it, each with an in and out port and a physical switch that can be used to change the attenuation manually. It is, as stated, programmable and we were able to use commands from the firmware manual to do what we needed with the code. Attenuator commands allow us to do many things with the attenuators but the two commands we took advantage of in this version are the set attenuator command, which allows us to set specific attenuations to specific attenuators, and the fade attenuator command, which allows us to fade between two attenuations for a specific attenuator. These two commands gave us the functionality we needed to create more realistic movement models.

Before detailing the functions, lets take a quick look at the first section of the code. (There are comments throughout the code for clarity as well). The first step of our code automatically telnets into the machine for us, giving us full access to all the commands provided by the attenuator. From there we set the attenuators to specific values: 0dB on attenuator 1 and -95 dB on attenuator 2. This just allows each test to start with the a similar environment, for repeatability’s sake. Next we lay out all the parameters for the specific functions. These parameters will be explained further on.

The last thing present before the code for the actual functions is a output to the user that is a small, basic description of the different options. Then we go into the interact loop which hands the process over to the user to decide which function to complete.

An example of the ouput in the beginning of the program.

As mentioned briefly in our introduction, our code contains three options for the users. Below is described the functionality of each in detail, the required user input parameters, and a brief description of the actual code behind the function. (With "user input parameters", we are referring to variables and arrays that we will eventually have the user provide. For now, these are simply defined at the start of the code)

Separate Points of Attenuation at Separate Times

As suggested by the name, this function takes an array of attenuation points and puts them into the attenuator with no interpolation. The array key is considered the timestamp for that attenuation. So the value at array(1) is the value the attenuator will show at time one. The array key will be considered the timestamp for all of the functions. The user must also input how long each timestamp is in seconds. So if a user says 3, then array(2) is really occurring at second 6.

The actual array does not have to be continuous. Users can input for times 1, 3, and 5 and the code will still work. A dictionary [2] is nested inside each key of the array and contains the attenuation values for all the attenuators allotted to the experiment. Our code is developed so that the amount of attenuators used is dynamic.

The actual code starts at 0 and increments up, stopping at each location that has an input value and sending that value to the attenuator. It then pauses so that we stay in line with the timestamps. If no value is given, the code simply pauses the time needed per step to simulate no change. It then continues incrementing and checking. Each time we find a value, we increment the number of successful updates we’ve completed. This number is then compared to the length of the inputed array to ensure we stop checking once we’ve reached the end of the array.

The output to the user is a time in seconds at each update to the system and the attenuation values for both of the attenuators. This lets the user easily track the progress of the system. Users should note that the system will pause if no update is asked and will say “Done.” when the process is completed.

Example of output to user and the done message.​

Connected Points (Linear Interpolation) for a Given 'Path' of Attenuation Values

This function creates a more realistic path of attenuation. It takes an array of points, much like the one used in the first function, with each timestamp having an attenuation reading, and linearly interpolates between the points so that movement is more smooth and realistic. This function is especially created for people who have measured and recorded some movement in real life and want to “play it back” on the test bed.

User input for this is again an array with nested dictionaries. For this function, we are expecting that each timestamp has a value (starting at 0), so there are no gaps in time without updates. This is because we believe that it is a recording of sorts so the user will give us attenuations for each point. Keep in mind the points don’t have to be for every second since the user also inputs the time for each timestamp, much like in the above function (again timestamps 1 2 3 could really be seconds 3 6 9).

Our code again starts by finding how many values are given in the array. Next, we go through each part of the array, starting at zero, and going up till 1 before the last point. For each point, we find the attentuation (in dB) of that point and of the next one (thus why we stop one before the end). We then use the fade function, which allows us to increment automatically from one value to another every however many milliseconds. To find the amount of milliseconds, we take the time the user gave for each timestamp and multiply it by 1000 (gets it into milliseconds) and then divide it by the number of steps needed to be taken for that fade. This gives us all the values needed to fade between each point and the next. In this way we continue until we have reached the last attenuation.

Output includes the time at each update to the system in seconds. It also continuously displays the attenuation of both systems, allowing you to easily track the fade as it happens. When completed, the function will send “Done.” to the user. Note that for this function, the done may be followed by another output concerning the completion of a specific fade. This is because we cannot determine which attenuator will finish first, so we can’t specify what message to wait for. This should not have an effect on the overall timing however.

Example of output to the user and done message. Note the location of the done message (see above for details).

Motion Model Based on Geometric Inputs

The third function creates a different way for users to input data. If they don’t know the attenuation values they want but they want to be able to test movement around base stations, they can use this function. It allows them to use geometric inputs based on a basic (x,y) cartesian plane for the UE locations at different times. The function then finds the attenuations from these locations to the base stations, the location of which the user also determines, and thus simulates the wanted movements.

The first input from the user is an array with nested dictionaries that contains the geometric position of the UE. This position is made up of an x and y coordinate. These are measured in meters from a (0,0) origin (you can input negatives and decimals too). We again have a timestamp that dictates the timing of each point. We also don’t need points for every timestamp. For example, a user could say I want to be at (10,30) at time 0 and at (45, 20) at time 10 and the code would be able to use that and give back a accurate motion model between those points. Note however that the code is expecting a location for time 0. The user must also enter how long each timestamp is, just like the previous functions. Finally, the user must enter some variables to be used in the COST Hata Model (see below). These include UE and base station height (currently held constant for all base stations) and whether the experiment is in an urban or suburban environment.

Our code starts off by reorganizing the input. It takes the user supplied geometric data and puts it into a new array that places the timestamp as yet another dictionary value. This allows us to easily access the different points in a simpler matter later on. This also allows us to determine the total amount of updates to be done. In this function, we update several times a second (user inputs the number of updates per second too). Once we have the total number of updates to be done (time the user wants the experiment to run * updates per second), we start at update 0 in a for loop and go till the limit determined earlier. Each time we have a new update, we figure out between which two user provided geometric points this update lies and then use those two surrounding points to determine the exact location at that single update point. In the next step, the program takes the x and y location we just found and finds how far it is from each base station using the pythagorean theorem. These distances then independently plugged into the COST Hata Model [1]:

L  =  46.3 + 33.9log(f) - 13.82log(hB) - a(hR) + [44.9 - 6.55log(hB)]log(d) + C


a(hR) = (1.1log(f) - 0.7)hR - (1.56log(f) - 0.8)

C = 0dB for medium cities and suburban areas
C = 3dB for metropolitan areas

L = Median path loss. Unit: decibel (dB)
f = Frequency of Transmission. Unit: megahertz (MHz). Must be between 150 and 2000 MHz.
hB = Base station antenna effective height. Unit: meter (m). Must be between 30 and 200 m.
d = Link distance. Unit: Kilometer (km). Should be between 1 and 20 km.
hR = Mobile station antenna effective height. Unit: meter (m). Must be between 1 and 10 m.
a(hR) = Mobile station antenna height correction factor as described in the Hata model for urban areas. (see above)

The model takes all these variable inputs and spits out an attenuation value (dB). Due to the high distance (between 1 and 20 km) we tend to get attenuations that are "higher" than we can set. We assume that the attenuator has about 40 dB insertion loss added onto every programmed value. For the final PhantomNet project, we will measure and incorporate this more precisely and we will consider tinkering with the base stations's power in order to emulate even higher attenuations. But for now we just assume 40 dB loss, so we subtract 40 dB from all the attenuations.

These we then plug into the set attenuator command. After that we pause for the amount of time indicated for each update. This we repeat until we reach the last given location. With this high speed updating, we allow a smooth, realistic motion model to be created based off of geometric values. One quick note, in order to allow for a cleaner output/execution, we only update the attenuator if the value to be sent to it changes.

The output for this function is, as before, a time in seconds followed by the respective attenuations. Again, when completed, the function will declare that it is “Done”. Also remember that the system pauses while waiting for the next input. Unless the done message has been set, the motion model is not yet completed.

Example of output to the user and done message.


In terms of testing these functions, there is not much we can do. Due to the fact that the PhantomNet project is waiting on some hardware, we cannot yet perform more precise and enlightening tests in terms of whether the attenuator does what we need it to do in terms of actually effecting the signal. So that means that for functions 1 and 2, we need to wait until we are ready with the new hardware. But for function 3, we needed to test to be sure that the math was correct and we were getting the right numbers.


In order to test this, we essentially inputed all the parameters needed and with a calculator, got the distance and attenuation in the same way the function does it. So using the pythagorean theorem, we found the distances for the values inputed. After doing that we used the Hata model to find the attenuation for those distances. Finally we went into the code and printed the distances and attenuations that the program found, so that we could compare them. You can still print out the distances and attenuations by uncommenting the two send_user lines in the third function. This will allow you to see the distance and attenuation for every potential update. If you'd like to see for the specific times we calculated, you will have to match up the update number to the second. This will depend upon the seconds per time slot and the rate of updates.

Below are the inputs I gave the system and the numbers I calculated separately (all locations are in meters from point (0,0)):

Base Station Locations:
Base station 1: x=0 y=1000
Base station 2: x=1000 y=3000

UE Height = 2 m
Base Station Height = 100 m (For both)
C = 0
Time = 3 seconds per timestamp

UE Locations:
Timestamp:    x:   y:
0:          0    1000
3:          67   1000
11:         245  1060
15:         335  1100

UE timestamp 0 to Base 1: 1 km
UE timestamp 0 to Base 2: 2.236 km
UE timestamp 3 to Base 1: 1.002 km
UE timestamp 3 to Base 2: 2.206 km
UE timestamp 11 to Base 1: 1.087 km
UE timestamp 11 to Base 2: 2.081 km
UE timestamp 15 to Base 1: 1.149 km
UE timestamp 15 to Base 2: 2.013 km

Attenuation: (rounded to nearest whole number like in the program)
UE timestamp 0 to Base 1: 128 dB
UE timestamp 0 to Base 2: 139 dB
UE timestamp 3 to Base 1: 128 dB
UE timestamp 3 to Base 2: 139 dB
UE timestamp 11 to Base 1: 129 dB
UE timestamp 11 to Base 2: 138 dB
UE timestamp 15 to Base 1: 130 dB
UE timestamp 15 to Base 2: 138 dB


Comparing these numbers we calculated separately to the ones that the system calculated, we ended up with the exact same answers for both distance and attenuation meaning the code is working as it should. This allows us to confidently say that the numbers being displayed by the program are accurate.


By using our expect script, we can emulate realistic movement for the PhantomNet project, giving users the ability to use our code in order to test and ensure their code works in real world situations. Our code is flexible to the user, allowing them several different options to choose from. The code allows the user to input separate attenuation points at separate timestamps, a linear interpolation of inputed points in order to play back attenuations, and a geometric input using function which allows the user to show us in a more physical manner what they want to test. This is a good start for creating an easy to use, realistic, highly repeatable testbed.


  1. COST Hata model
  2. Dictionary Man Page (Tcl)