Aimsun Next V2X SDK Programming¶
Introduction¶
The V2X Software Development Kit (SDK) is designed to allow a modeler access to the core V2X framework in Aimsun Next to implement connected vehicle VANets within a simulation. A VAnet is an ephemeral network spontaneously created by a collection of connected vehicles in proximity to each other. VANets are formed as vehicles detect transmissions from other vehicles then, while they are in range of each other, they are able to exchange information about their location and activity. By aggregating this information a vehicle is able to infer the pattern of the traffic around it and hence amend its own behavior accordingly.
A VANet can also include a static wireless station in a Roadside Unit (RSU), in effect a part of the road network management infrastructure. Including an RSU fixes the location of a VANet and gives it a permanent presence, its members then become the connected vehicles in the adjacent area. If that RSU is then linked to the network Traffic Management System (TMC), it becomes both a data gathering tool and an information dissemination device as a part of the wider ITS system.
The V2X core framework implemented in Aimsun Next is designed to add communication simulation to a dynamic traffic model and simulate the passing of messages between connected vehicles in ad-hoc network and between connected vehicles and an RSU. Within each vehicle, a modeler will use the classes and methods developed with the V2X SDK to collect these messages and use them to modify the behavior of the vehicle. Within each RSU, the modeler will similarly collect messages from vehicles within range of that RSU and either process them locally, or relay them to a central TMC which can derive a co-ordinated set of management responses to be relayed to vehicles via the V2X framework, or by conventional ITS mechanisms.
The V2X framework is therefore intended to enable simulation of collaborative behavior between vehicles and also co-ordinated behavior through management center controls which are based on a rich data flow from connected vehicles and ITS infrastructure roadside units.
V2X SDK Programming¶
The V2X SDK departs from the functional programming used in most of the Aimsun Next API. It uses object-oriented concepts to enable the programmer to develop new classes for objects such as Messages and Rules Engines which are based on template classes. A programmer using the V2X SDK should be familiar with these concepts in C++.
Object Oriented Class Inheritance¶
One of the key concepts use in the V2X SDK is class inheritance. A template class is used to provide the structure of a type of object and specialized classes inherit methods and data from the template. For example, the V2X::Message class (below) is the template and the V2X::CAMMessage, V2X::SPATEMMessage, and V2X::MAPEMMessage classes are specializations of that template. Each of the classes for specific types inherit the methods and data of the V2X::Message and each adds to it the methods and data specific to that message type.
The V2X::MyMessage class is a user supplied message type, developed for a specific application. The class is created by the setup method called as the V2X::MyFramework class is loaded at start up time and registered with the V2X Framework within Aimsun Next.
When in use, messages of type V2X::MyMessage are passed between devices in the same manner as other message type. This is because the message passing algorithms handle objects of class V2X::Message and therefore automatically handle all message types which inherit that template class. Therefore, there is no extra work required in the core of the V2X system to enable new message types to be distributed.
V2X Components ¶
The components of the V2X Framework are described in the V2X User Interface Section where they are created and edited. The components are:
-
Message Type: The types of messages passed between vehicles and the RSUs.
-
Channel: The communications channel is the simulated representation of the radio hardware and protocols that provide communications between vehicles.
-
On Board Unit: The OBU provides the receiver and transmitter in a vehicle.
-
RoadSide Unit(RSU): The RSU is the "I" component of the Vehicle to Infrastructure (V2I) communications network. It is a roadside device with a specified location and can also be linked to a junction, or number of junctions.
-
Traffic Management Center: The Traffic Management Center is the integrator of the data from multiple RSUs and the initiator of co-ordinated signal control and traffic management actions as well as triggering V2X messages to be transmitted from the RSUs.
The API component that undertakes the actions for each of the vehicles, RSUs, and TMCs in the simulation is a Rules Engine. A Rules Engine is a specialization of a V2X::RulesEngine class and is responsible for processing the list of messages received by the OBU, RSU or TMC, processing the data in these messages, then taking whatever action deemed to be necessary using algorithms designed and coded by the modeler.
In the simple cases, where the message types are those already supplied in the V2X framework and the channel characteristics adequately represent the transmission range, latency, and packet losses, the only API code to be written is a rules engine for those objects with changed behaviors.
Installation ¶
The V2X SDK is installed in two stages:
- The V2X Framework which installs the plug-in to Aimsun Next. It must be installed in the folder where you installed Aimsun Next 24
- The V2X SDK which installs the user documentation, the V2X SDK libraries and header files and in the /include/aimsun_extensions/v2x/samples directory, an example V2X SDK project. It must be installed in a folder with writing permissions.
Contact Aimsun to request the two installers by sending an email to info@aimsun.com
Other software requirements before starting coding are:
- Visual Studio 2019 or more recent, set up to use with Visual C++.
- Qt 5.14 or more recent. You can download it from https://www.qt.io/download. As a clarification, Qt is available as a free open-source version.
- Qt VS Tools add-in for Visual Studio, these need to be installed from Visual Studio as an extension (in Visual Studio, click on ‘Extensions’ > ‘Online’ > Search for ‘Qt’ > Install ‘Qt Visual Studio Tools’
Setting up¶
- Make sure to have installed both the V2X Framework and V2X SDK as well as all previous requirements.
- Access the ‘StopEngine’ folder located inside the V2X SDK installation folder as follows: ‘/include/aimsun_extensions/v2x/samples/StopEngine’
- Start Visual Studio and configure the Qt VS Tools by clicking on ‘Extensions’ > ‘Qt VS Tools’ > ‘Qt Options’. In the Qt Options window, select the appropriate Qt installation.
- Open the project file by clicking on ‘Extensions’ > ‘Qt VS Tools’ > ‘Open Qt Project File’. Select the StopEngine.pro file and compile as you would normally.
- Once it has finished, copy the generated DLL alongside the StopEngine.xml file and place them inside ‘/Aimsun Next 24/plugins/dynamicAPIS’. If the ‘dynamicAPIS’ folder does not exist, create it.
The V2X setup process should have concluded correctly. Open a V2X sample model and verify that everything is set up as expected.
Class Documentation ¶
The automatically generated documentation for the V2X SDK is provided in the distribution Open the file Program Files/Aimsun Next 24/docs/html/index.md to access the software documentation
This documentation should be consulted when programming with the V2X SDK as it is generated from the source code and details all classes, their interrelationships, and their methods.
V2X Classes ¶
The key classes used in developing a V2X application are the V2X::Framework class, the V2X::Message class, and the V2X::RulesEngine class.
V2X::Framework¶
This is the template class for V2X project management. The programmer must create a specialization of this to form a V2X:MyFramework class based on this template class.The new class must supply the setup function to initialize the V2X system as the programmed library is loaded and a destructor function which runs at the end of the simulation to close any external links and output any summary data as the V2X::MyFramework object is destroyed.
Setup Method¶
The setup method for the framework is called by the constructor method. It is used to:
- Create and register new message types
- Add attributes to vehicles or roadside units to enable them to hold information about their V2X activity.
- Create and register new communications channel types with more, or different, functionality than the default type.
New messages and new channels will be added to the list presented in the V2X OBU editor and RSU editor after creation.
Action Methods¶
The V2X::Framework class also contains four virtual functions called during the simulation:
- arrivalNewVehicle: Called when a vehicle enters the simulation.
- removedVehicle: Called when a vehicle leaves the simulation.
- preUpdate: Called at the beginning of each simulation step.
- postUpdate: Called at the end of each simulation step.
These four methods are called at significant events in the simulation: as vehicles enter and leave, and before and after every timestep. The actions typically would be:
- On new vehicle event:
- Set up any initialization data for the rules engine which will control the new vehicle.
- On vehicle leaving event:
- Log any cumulative data about V2X related activity for that vehicle.
- On preUpdate, gather data which might be relevant to the V2X communications:
- Data from other ITS systems operating in the simulation.
- Network status, proxying the data available in a traffic control center
- On postUpdate, perform any actions determined using V2X data:
- Give information to other ITS systems operating in the simulation.
Get Rules Engine Method¶
The GetRulesEngine Method is called by the init method of the V2X::Framework class and is used to generate a V2X::RulesEngine for each device type.
std::unique_ptr<V2X::RulesEngine> MyFramework::getRulesEngine( V2X::Device::DeviceType dType GKObject *oType ) const
{
if( dType == V2X::Device::DeviceType::eObu &&
oType->getTypeName() == "802.11p"){
// an OBU of a specific type
MyVehicleRulesEngine* rulesEngine = new MyVehicleRulesEngine();
std::unique_ptr<V2X::RulesEngine> vres( rulesEngine );
return vres;
}
else if( type == V2X::Device::DeviceType::eRsu ){
MyRSURulesEngine* rulesEngine = new MyRSURulesEngine();
std::unique_ptr<V2X::RulesEngine> rres( rulesEngine );
return rres;
}
else
{
return nullptr;
}
This creates the link by which the simulation can call the Rules Engine callbacks to deliver the V2X::Messages.
V2X::RulesEngine ¶
The V2X::RulesEngine class is the template class for a Rules Engine. The programmer must create a V2X::MyRulesEngine class which inherits the V2X::RulesEngine class and implements the action methods according to the project requirements.
A V2X::MyRulesEngine class is required for each of the device types used in the simulation and is created in the GetRulesEngine Method called by the init method of the V2X::Framework class as the simulation is loaded.
The Rules Engine has two main methods:
- evaluate: Called before the timestep is executed. This method delivers all the incoming messages to each simulation agent with a V2X::Device. The evaluate method is used to gather data.
- performActions: Called after the timestep has been executed. This method is used to implement any actions required by agent connected to the device.
These methods are called at every time step for every device in the simulation. The class is instanced for every device and hence can hold state information about itself or the agent (i.e. the vehicle) that the device is associated with. For example, this might be the last time of transmission or the last transmitted state so that transmission might be made only after a significant change.
An example of an Evaluate method which receives messages and adds them to the agent's data:
void MyRulesEngine::evaluate( double time )
{
for( auto message : mMessages )
{
if( message->getType() == V2X::Message::eCustom ){
const auto cMessage = std::dynamic_pointer_cast<MyMessage >(message);
if(cMessage){
//Get the data and the device
const auto & data = cMessage->getData();
auto agent = mDevice->agent();
// collate the data
agent->addToKnowledge(data->mydata);
}
}
}
An example of a performActions method which executes V2X related actions every time step and also sends a V2X message every 10 seconds:
void MyRulesEngine::performActions( double time )
{
auto agent = mDevice->agent();
if( agent != nullptr)
{
auto id = mDevice->getId();
\\ PerformActions with vehicle id
agent->instantaction();
}
//creation and transmission of custom messages every 10 seconds
int trunkTime = static_cast<int>(time);
if ( trunkTime % 10 == 0 )
{
auto message = std::make_shared<MyMessage>();
auto & data = message->data();
fillmessage(data); // Find what we want to transmit
//select channels and set the messages to be send
auto deviceChannels = mDevice->getChannels();
for( auto channel : deviceChannels )
{
mDevice->addOneTimeMessage( message, channel->getId() );
}
}
}
V2X::Device ¶
The V2X::Device class describes the V2X object attached to a simulation agent, i.e. a vehicle. The device is the object used by the Rules Engine to transmit messages. The methods available to do this are:
- addOneTimeMessage(message, channel): Add a user defined Message to the messages that will be sent on the next timestep.
- removeOneTimeMessage( message ): Remove all instances of a user defined message from the list of messages that will be sent at the next timestep.
- removeOneTimeMessage( message, channel ): Remove the instances of user defined message on a specified channel.
- clearOneTimeMessages(): Removal of all user defined messages from the m
Note that the generateMessages method must be called before these methods or the action will fail.
V2X::Message ¶
This is template class for V2X messages. While several standardized message types are provided in the V2X SDK, many innovative applications will require new message types are created. Within the V2X SDK, this is done by creating a new class that inherits from the V2X::Message class.
The following is an example of a new message class which inherits the V2X::Message class.
class MYV2XFRAMEWORKEXPORT MyMessage : public V2X::Message
{
public:
MyMessage(); // Constructor
~MyMessage(); // Destructor
// Message Type
virtual messType getType() const override { return eCustom; }
// housekeeping methods
virtual V2X::Message * copy() const override;
virtual void print() const override;
virtual quint32 getSize() const override;
// Get data as a copy. a constant or a pointer
MyData getCopyData() const { return mData;}
const MyData & getData() const { return mData; }
MyData & data() {return mData;}
private:
MyData mData;
};
In the V2X::MyFramework initialization, this message is included in the list presented in the user interface in the setup method by calling:
V2X::Framework::registerMessage("MyMessageName", "Message Description");
The code then implemented to send the message in the performActions method of the Rules Engine must:
- Create the message.
- Fill the MyData structure.
- Add the message to the channels it is to be sent on
This is shown in the sample code for the V2X::MyRulesEngine class above.
Workflow¶
The consolidated workflow is therefore:
-
At Initialization, in the V2X::MyFramework setup method:
- Create message types and register them with the GUI.
- Create rules engines for devices.
-
At each timestep for the Framework:
- Use the preUpdate and postUpdate callback methods to manage the V2X Framework.
-
For each vehicle
- Initialize its V2X data as it enters the traffic network when it is generated.
- Close its V2X activity as it leaves the traffic network at the end of its trip.
-
At each timestep for all agents with active V2X devices:
- The evaluate callback is called prior to the timestep execution.
- The performActions callback is called after the timestep execution.