Smart-AHS sensor subsystem architecture has been designed to be expandable and easy to use. The design is given as a set of superclasses that are used as the foundation of various types of sensors. Since sensor technology can vary, it was necessary to abstract the behavior of sensing devices by factoring their common features.
Smart-AHS provides the following three-layered sensor architecture of SHIFT types:
New sensors can be written by inheriting from the described superclasses (which preserves the interfaces). Also note that the described root types are to be considered abstract. This means that their implementation isn't complete. They should be used only as supertypes. This structure has been used to implement a realistic radar sensor model, which also takes into account weather conditions.
In order to improve performance, some optimization techniques have been used. The roads are divided in cells and sensors actually check for other vehicles only in the neighboring cells. This avoids checking all the vehicles in the simulated world, which is an n2 time process. The managment of cells is taken care of by a special type called SEP (Sensor Environment Processor).
The user only needs to be aware of the SEP type, the Sensor type and their subtypes. The other layers are hidden.
Implementing sensors brought up a performance problem. How is a sensor to determine whether a car is within range? The easiest solution is to look for such a car in the set of all the cars in the world. This is obviously very expensive.
To avoid this, road sections have been subdivided in cells. Each cell corresponds to a set of vehicles. Cars move from cell to cell: when they cross a cell border, they add themselves to the new cell and remove themselves from the old one.
The SEP takes care of updating the cells. The means by which this task is performed is hidden from the user. All the user has to know is how to instantiate the SEP and how to connect it to the other components.
If the istantiation happens inside the vehicle, the create statement looks like this (from now on the italic font is used to denote a reference to a specific component):
SEP sep := create ( SEP, the_vehicle := self, current_segment := starting_segment, current_section := starting_section, current_cell := cells (starting_section)[0] );
The inputs of the SEP can be set with the following connections:
rxp (sep) <- rxp (vrep);
ryp (sep) <- ryp (vrep);
rzp (sep) <- rzp (vrep);
current_lane (sep) <- lane (vrep);
current_segment (sep) <- segment (vrep);
current_section (sep) <- section (vrep);
followLane (sep) <- followLane (vrep);
the_vehicle (sep) <- self;
vehicle_sensors (sep) <- {...};
The outputs of the SEP are:
Note that cell specific informations such as cell length are set up in the Section type. The number of cells is obtained from the length of the section and that of the cells.
A Smart-AHS vehicle has one SEP and zero or more sensors. Four sensor links are provided in the Vehicle type: frontSensor, rearSensor, leftSensor and rightSensor. Others may be added in the subtypes of Vehicle.
The Sensor abstract superclass requires the following inputs:
The timer type is used to select a sampling time for the sensor.
The outputs of the sensor are the following:
Range is the distance in meters from the detected vehicle. Actually the range is calculated by subtracting half the length of the following car and half the length of the leading car from the distance between the two cars. This method assumes that cars have circular shapes.
Range rate is the difference between the speed of the detected vehicle and the speed of the current vehicle.
The target type encapsulates the detected vehicle. It has the following outputs:
Note that the distance in the target doesn't take into account the length of the vehicles.
A few sensors have been implemented on top of the described architecture. Their source code can be studied as an example of implementation.
The lowest level of the architecture fulfills the purpose of detecting targets if any. It does not simulate any noise. Its function is purely geometric: e.g. to understand wether a vehicle exists, that falls within the sensor range. For this reason TargetDetectors can be categorized according to the shape of their detection field.
The inputs of this type are:
The outputs are the same as the sensor class. They are actually processed by the upper level before being passed to the sensor. Three transitions take place. It is important that all of them be present:
This is the middle layer and it serves as a noise generator. The perfect results of the Target Detector are read and distorted according to a specific model.
The only input of this type is the fap (false alarm probability) which is optional in some models. It is a value between 0 and 1 and it's used to generate false alarms.
The outputs are:
Dp is the detection probability, which is calculated according to the model. The last three values are read from the corresponding targetDetector but can be changed according to some function of fap and of dp.
The state variables are not inherited, so they are included in the root class only as conceptual placeholders. They are:
RE and rrE are the range error and the range rate error.
There must be at least one transition synchronizing on enclosingSensor:update_values. It reads the values in the lower levels and distorts them. Of course there may be more than one such transition (e.g. one for regular detection, one for failed detection, one for false alarms and so on).
The public interface ( input and outputs ) of the higher layer has been described already so we'll talk about the private one here.
Two state variables (targetDetector and sensorModel) should be used to link the sensor to its TargetDetector and to its SensorModel. A setup clause should be present to istantiate and initialize correctly these two components.
Two local events are exported:
They are used for synchronization with lower levels.
Reading the values from the TargetDetector can be done in two ways. The easiest way is via a flow:
flow
default {
range = range(targetDetector);
rangeRate = rangeRate(targetDetector);
};
The second one is via transitions such as:
idle -> update {update_values},
update -> idle {values_updated};
Note that two such transitions must be present anyway because they are used by lower level types and also because in this way the sensor signals it is updating its values to other interested types (e.g. automated cruise control types).
Some implementation techniques can be studied by reading the sensors/sensor.hs file in the Smart-AHS distribution.