├── Vissim Tutorial.zip ├── Vissim External Driver Model DLL Tutorial.docx ├── README.md └── DriverModel.cpp /Vissim Tutorial.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YunpengShi/Using-VISSIM-External-Driver-Model-DLL-for-Modeling-Mixed-Traffic-with-Both-Automated-Vehicles-and-H/HEAD/Vissim Tutorial.zip -------------------------------------------------------------------------------- /Vissim External Driver Model DLL Tutorial.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YunpengShi/Using-VISSIM-External-Driver-Model-DLL-for-Modeling-Mixed-Traffic-with-Both-Automated-Vehicles-and-H/HEAD/Vissim External Driver Model DLL Tutorial.docx -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Using VISSIM External Driver Model DLL for Modeling Mixed Traffic with Both Automated Vehicles and Human-driven Vehicles 2 | 3 | 4 | Hi, all! 5 | This is a tutorial on how to use external driver model function of PTV Vissim to model mixed traffic with both automated vehicles and human-driven vehicles. You can directly read the word and cpp file, or download the Vissim Tutorial ZIP file which include everything. 6 | Thank you and have a nice day! 7 | -------------------------------------------------------------------------------- /DriverModel.cpp: -------------------------------------------------------------------------------- 1 | /*==========================================================================*/ 2 | /* DriverModel.cpp DLL Module for VISSIM */ 3 | /* */ 4 | /* Interface module for external driver models. */ 5 | /* Dummy version that simply sends back VISSIM's suggestions to VISSIM. */ 6 | /* */ 7 | /* Version of 2010-03-02 Lukas Kautzsch */ 8 | /*==========================================================================*/ 9 | 10 | #include "DriverModel.h" 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | 23 | /*==========================================================================*/ 24 | /*Default Parameters*/ 25 | 26 | double desired_acceleration = 3.5; 27 | double desired_lane_angle = 0.0; 28 | long active_lane_change = 0; 29 | long rel_target_lane = 0; 30 | double desired_velocity = 13.9; 31 | long turning_indicator = 0; 32 | long vehicle_color = RGB(225,225,225); 33 | 34 | /*==========================================================================*/ 35 | /*Create Variables*/ 36 | 37 | double current_time; 38 | long current_vehicle; 39 | double current_velocity; 40 | double current_acceleration; 41 | double vehicle_length; 42 | double vehicle_x_coord; 43 | double vehicle_y_coord; 44 | long vehicle_type; 45 | int vehicle_current_link; 46 | double gross_distance; 47 | double speed_difference; 48 | double ahead_vehicle_acceleration; 49 | double signal_distance; 50 | double s_star; 51 | double distance = 0; 52 | double stopline_x_coord; 53 | double stopline_y_coord; 54 | double car_following_acceleration; 55 | double ahead_vehicle; 56 | double phase; 57 | //long category; 58 | 59 | 60 | static int vehicle_count = 0; 61 | static int veh = -1; 62 | static int vehicle_to_stop = 0; 63 | 64 | /*==========================================================================*/ 65 | /* IDM parameters and equation*/ 66 | 67 | double a = 1.5; // maximum acceleration, constant a (m/s^2) 68 | double b = 3; // maximum deceleration, constant b (m/s^2) 69 | double IDM_desired_velocity = 15; // desired velocity uesd in IDM (m/s) 70 | double v0 = IDM_desired_velocity; 71 | double jam_distance = 0.6; // minimum gross distance (m) 72 | double S0 = jam_distance; 73 | double T = 0.6; // safe-time headway (s) 74 | 75 | double S_star(double v, double v_delta) 76 | { 77 | double S_star = S0 + (v * T) + ((v * v_delta) / (float)(2 * sqrt(a*b))); 78 | return S_star; 79 | } 80 | 81 | 82 | 83 | double euclid_dist(double x1, double y1, double x2, double y2) 84 | { 85 | double x_diff = x2 - x1; 86 | double y_diff = y2 - y1; 87 | double euclid_dist = sqrt(pow(x_diff, 2) + pow(y_diff, 2)); 88 | return euclid_dist; 89 | } 90 | 91 | 92 | /*==========================================================================*/ 93 | 94 | BOOL APIENTRY DllMain (HANDLE hModule, 95 | DWORD ul_reason_for_call, 96 | LPVOID lpReserved) 97 | { 98 | switch (ul_reason_for_call) { 99 | case DLL_PROCESS_ATTACH: 100 | case DLL_THREAD_ATTACH: 101 | case DLL_THREAD_DETACH: 102 | case DLL_PROCESS_DETACH: 103 | break; 104 | } 105 | return TRUE; 106 | } 107 | 108 | /*==========================================================================*/ 109 | 110 | DRIVERMODEL_API int DriverModelSetValue (long type, 111 | long index1, 112 | long index2, 113 | long long_value, 114 | double double_value, 115 | char *string_value) 116 | { 117 | /* Sets the value of a data object of type , selected by */ 118 | /* and possibly , to , or */ 119 | /* <*string_value> (object and value selection depending on ). */ 120 | /* Return value is 1 on success, otherwise 0. */ 121 | 122 | switch (type) { 123 | case DRIVER_DATA_PATH : 124 | case DRIVER_DATA_TIMESTEP : 125 | case DRIVER_DATA_TIME : 126 | current_time = double_value; 127 | return 1; 128 | case DRIVER_DATA_VEH_ID : 129 | current_vehicle = long_value; 130 | return 1; 131 | case DRIVER_DATA_VEH_LANE : 132 | case DRIVER_DATA_VEH_ODOMETER : 133 | case DRIVER_DATA_VEH_LANE_ANGLE : 134 | case DRIVER_DATA_VEH_LATERAL_POSITION : 135 | case DRIVER_DATA_VEH_VELOCITY : 136 | current_velocity = double_value; 137 | return 1; 138 | case DRIVER_DATA_VEH_ACCELERATION : 139 | current_acceleration = double_value; 140 | return 1; 141 | case DRIVER_DATA_VEH_LENGTH : 142 | vehicle_length = double_value; 143 | return 1; 144 | case DRIVER_DATA_VEH_WIDTH : 145 | case DRIVER_DATA_VEH_WEIGHT : 146 | case DRIVER_DATA_VEH_MAX_ACCELERATION : 147 | return 1; 148 | case DRIVER_DATA_VEH_TURNING_INDICATOR : 149 | turning_indicator = long_value; 150 | return 1; 151 | case DRIVER_DATA_VEH_CATEGORY : 152 | //category = long_value; 153 | //return 1; 154 | case DRIVER_DATA_VEH_PREFERRED_REL_LANE : 155 | case DRIVER_DATA_VEH_USE_PREFERRED_LANE : 156 | return 1; 157 | case DRIVER_DATA_VEH_DESIRED_VELOCITY : 158 | desired_velocity = double_value; 159 | return 1; 160 | case DRIVER_DATA_VEH_X_COORDINATE : 161 | vehicle_x_coord = double_value; 162 | return 1; 163 | case DRIVER_DATA_VEH_Y_COORDINATE : 164 | vehicle_y_coord = double_value; 165 | return 1; 166 | case DRIVER_DATA_VEH_TYPE : 167 | vehicle_type = long_value; 168 | return 1; 169 | case DRIVER_DATA_VEH_COLOR : 170 | vehicle_color = long_value; 171 | return 1; 172 | case DRIVER_DATA_VEH_CURRENT_LINK : 173 | vehicle_current_link = long_value; 174 | return 1; /* (To avoid getting sent lots of DRIVER_DATA_VEH_NEXT_LINKS messages) */ 175 | /* Must return 1 if these messages are to be sent from VISSIM! */ 176 | case DRIVER_DATA_VEH_NEXT_LINKS : 177 | case DRIVER_DATA_VEH_ACTIVE_LANE_CHANGE : 178 | case DRIVER_DATA_VEH_REL_TARGET_LANE : 179 | case DRIVER_DATA_NVEH_ID : 180 | if (index1 == 0 && index2 == 1) { 181 | ahead_vehicle = long_value; 182 | } 183 | //adj_vehicle[0][1] = long_value; 184 | return 1; 185 | case DRIVER_DATA_NVEH_LANE_ANGLE : 186 | case DRIVER_DATA_NVEH_LATERAL_POSITION : 187 | case DRIVER_DATA_NVEH_DISTANCE : 188 | if (index1 == 0 && index2 == 1) 189 | { 190 | gross_distance = double_value; 191 | } 192 | return 1; 193 | case DRIVER_DATA_NVEH_REL_VELOCITY : 194 | if (index1 == 0 && index2 == 1) 195 | { 196 | speed_difference = double_value; 197 | } 198 | return 1; 199 | case DRIVER_DATA_NVEH_ACCELERATION : 200 | if (index1 == 0 && index2 == 1) 201 | { 202 | ahead_vehicle_acceleration = double_value; 203 | } 204 | return 1; 205 | case DRIVER_DATA_NVEH_LENGTH : 206 | case DRIVER_DATA_NVEH_WIDTH : 207 | case DRIVER_DATA_NVEH_WEIGHT : 208 | case DRIVER_DATA_NVEH_TURNING_INDICATOR : 209 | case DRIVER_DATA_NVEH_CATEGORY : 210 | case DRIVER_DATA_NVEH_LANE_CHANGE : 211 | case DRIVER_DATA_NO_OF_LANES : 212 | case DRIVER_DATA_LANE_WIDTH : 213 | case DRIVER_DATA_LANE_END_DISTANCE : 214 | case DRIVER_DATA_RADIUS : 215 | case DRIVER_DATA_MIN_RADIUS : 216 | case DRIVER_DATA_DIST_TO_MIN_RADIUS : 217 | case DRIVER_DATA_SLOPE : 218 | case DRIVER_DATA_SLOPE_AHEAD : 219 | case DRIVER_DATA_SIGNAL_DISTANCE : 220 | signal_distance = double_value; 221 | return 1; 222 | case DRIVER_DATA_SIGNAL_STATE : 223 | phase = long_value; 224 | return 1; 225 | case DRIVER_DATA_SIGNAL_STATE_START : 226 | case DRIVER_DATA_SPEED_LIMIT_DISTANCE : 227 | case DRIVER_DATA_SPEED_LIMIT_VALUE : 228 | return 1; 229 | case DRIVER_DATA_DESIRED_ACCELERATION : 230 | desired_acceleration = double_value; 231 | return 1; 232 | case DRIVER_DATA_DESIRED_LANE_ANGLE : 233 | desired_lane_angle = double_value; 234 | return 1; 235 | case DRIVER_DATA_ACTIVE_LANE_CHANGE : 236 | active_lane_change = long_value; 237 | return 1; 238 | case DRIVER_DATA_REL_TARGET_LANE : 239 | rel_target_lane = long_value; 240 | return 1; 241 | default : 242 | return 0; 243 | } 244 | } 245 | 246 | 247 | /*--------------------------------------------------------------------------*/ 248 | 249 | DRIVERMODEL_API int DriverModelGetValue (long type, 250 | long index1, 251 | long index2, 252 | long *long_value, 253 | double *double_value, 254 | char **string_value) 255 | { 256 | /* Gets the value of a data object of type , selected by */ 257 | /* and possibly , and writes that value to <*double_value>, */ 258 | /* <*float_value> or <**string_value> (object and value selection */ 259 | /* depending on ). */ 260 | /* Return value is 1 on success, otherwise 0. */ 261 | 262 | switch (type) { 263 | case DRIVER_DATA_STATUS : 264 | *long_value = 0; 265 | return 1; 266 | case DRIVER_DATA_TIME: 267 | *double_value = current_time; 268 | return 1; 269 | case DRIVER_DATA_VEH_ID: 270 | *long_value = current_vehicle; 271 | return 1; 272 | case DRIVER_DATA_VEH_VELOCITY: 273 | *double_value = current_velocity; 274 | return 1; 275 | case DRIVER_DATA_VEH_ACCELERATION: 276 | *double_value = current_acceleration; 277 | return 1; 278 | case DRIVER_DATA_VEH_LENGTH: 279 | *double_value = vehicle_length; 280 | return 1; 281 | case DRIVER_DATA_VEH_TURNING_INDICATOR : 282 | *long_value = turning_indicator; 283 | return 1; 284 | case DRIVER_DATA_VEH_DESIRED_VELOCITY : 285 | *double_value = desired_velocity; 286 | return 1; 287 | case DRIVER_DATA_VEH_X_COORDINATE: 288 | *double_value = vehicle_x_coord; 289 | return 1; 290 | case DRIVER_DATA_VEH_Y_COORDINATE: 291 | *double_value = vehicle_y_coord; 292 | return 1; 293 | case DRIVER_DATA_VEH_TYPE: 294 | *long_value = vehicle_type; 295 | return 1; 296 | case DRIVER_DATA_VEH_COLOR : 297 | *long_value = vehicle_color; 298 | return 1; 299 | case DRIVER_DATA_VEH_CURRENT_LINK: 300 | *long_value = vehicle_current_link; 301 | return 1; 302 | //case DRIVER_DATA_NVEH_ID: 303 | //*long_value = adj_vehicle[0][1]; 304 | //return 1; 305 | case DRIVER_DATA_NVEH_DISTANCE: 306 | *double_value = gross_distance; 307 | return 1; 308 | case DRIVER_DATA_NVEH_REL_VELOCITY: 309 | *double_value = speed_difference; 310 | return 1; 311 | //case DRIVER_DATA_NVEH_ACCELERATION: 312 | // *double_value = ahead_vehicle_acceleration; 313 | // return 1; 314 | case DRIVER_DATA_SIGNAL_DISTANCE: 315 | *double_value = signal_distance; 316 | return 1; 317 | case DRIVER_DATA_WANTS_SUGGESTION : 318 | *long_value = 1; 319 | return 1; 320 | case DRIVER_DATA_DESIRED_ACCELERATION : 321 | *double_value = desired_acceleration; 322 | return 1; 323 | case DRIVER_DATA_DESIRED_LANE_ANGLE : 324 | *double_value = desired_lane_angle; 325 | return 1; 326 | case DRIVER_DATA_ACTIVE_LANE_CHANGE : 327 | *long_value = active_lane_change; 328 | return 1; 329 | case DRIVER_DATA_REL_TARGET_LANE : 330 | *long_value = rel_target_lane; 331 | return 1; 332 | case DRIVER_DATA_SIMPLE_LANECHANGE : 333 | *long_value = 1; 334 | return 1; 335 | default : 336 | return 0; 337 | } 338 | } 339 | 340 | 341 | 342 | /*==========================================================================*/ 343 | 344 | DRIVERMODEL_API int DriverModelExecuteCommand (long number) 345 | { 346 | /* Executes the command if that is available in the driver */ 347 | /* module. Return value is 1 on success, otherwise 0. */ 348 | 349 | switch (number) { 350 | case DRIVER_COMMAND_INIT : 351 | return 1; 352 | case DRIVER_COMMAND_CREATE_DRIVER : 353 | return 1; 354 | case DRIVER_COMMAND_KILL_DRIVER : 355 | return 1; 356 | case DRIVER_COMMAND_MOVE_DRIVER : 357 | if (vehicle_type == 700) 358 | { 359 | if(current_vehicle != vehicle_to_stop ){ 360 | 361 | double S = gross_distance - vehicle_length; 362 | double v = current_velocity; 363 | double v_delta = speed_difference; 364 | double s_star = S_star(current_velocity, speed_difference); 365 | 366 | car_following_acceleration = a * (1 - pow((v / (float)(v0)), 4) - pow((s_star / (float)S), 2)); 367 | 368 | if (gross_distance > jam_distance) 369 | { 370 | desired_acceleration = car_following_acceleration;// setting the IDM acceleration to the desired acceleration if gross distance is greater than the min gross distance 371 | } 372 | } 373 | 374 | if (ahead_vehicle < 0) { 375 | vehicle_to_stop = current_vehicle; 376 | } 377 | } 378 | return 1; 379 | default : 380 | return 0; 381 | } 382 | } 383 | 384 | /*==========================================================================*/ 385 | /* Ende of DriverModel.cpp */ 386 | /*==========================================================================*/ 387 | --------------------------------------------------------------------------------