Advertisement
Guest User

Untitled

a guest
May 22nd, 2018
83
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.79 KB | None | 0 0
  1. #include <cmath>
  2. #include <cstdio>
  3. #include <cstdlib>
  4. #include <ctime>
  5.  
  6. using namespace std;
  7.  
  8. /* car properties. */
  9. struct car_t
  10. {
  11. double position_x;
  12. double velocity_x;
  13. double desired_velocity;
  14. double desired_time_headway;
  15. double max_acceleration;
  16. double desired_deceleration;
  17. double acceleration_exponent;
  18. double jam_distance;
  19. double vehicle_length;
  20. double net_distance;
  21. double approaching_rate;
  22. };
  23.  
  24. double position_derivative(car_t o)
  25. {
  26. return o.velocity_x;
  27. }
  28.  
  29. double velocity_derivative(car_t o)
  30. {
  31. double term_a = exp(o.acceleration_exponent * log(o.velocity_x / o.desired_velocity));
  32.  
  33. double term_b_numerator_a = o.jam_distance + (o.velocity_x * o.desired_time_headway);
  34.  
  35. double term_b_numerator_b = (o.velocity_x * o.approaching_rate) / (2 * sqrt(o.max_acceleration * o.desired_deceleration));
  36.  
  37. double term_b_numerator_sum = term_b_numerator_a + term_b_numerator_b;
  38.  
  39. double term_b_dividend = term_b_numerator_sum / o.net_distance;
  40.  
  41. double term_b = exp(2 * log(term_b_dividend));
  42.  
  43. return (o.max_acceleration * (1 - term_a - term_b));
  44. }
  45.  
  46. int main (int argc, char **argv)
  47. {
  48. srand(time(NULL));
  49.  
  50. int n_cars = 10;
  51. double n_steps = 3600;
  52. double current_time = 0;
  53. double time_step = 1;
  54. double road_length = 1000;
  55.  
  56. /* loop over the car_ts to set the defaults in an array
  57. of car_t parameter structures. */
  58. car_t cars[n_cars];
  59. for (int i = 0; i < n_cars; i++) {
  60. /*
  61. * distribute the car_ts over the length of the road
  62. * equally. we don't know the net distace or the
  63. * approaching rate yet, so we leave these alone
  64. * for now.
  65. */
  66. car_t car;
  67. car.position_x = ((double)i / (double)n_cars) * road_length;
  68. car.velocity_x = 20.0;
  69. car.desired_velocity = 60.0;
  70. car.desired_time_headway = 1.5;
  71. car.max_acceleration = 1.0;
  72. car.desired_deceleration = 3.0;
  73. car.acceleration_exponent = 4.0;
  74. car.jam_distance = 2.0;
  75. car.vehicle_length = 5.0;
  76.  
  77. cars[i] = car;
  78. }
  79.  
  80. /* positions and velocities files. */
  81. FILE *positions, *velocities;
  82. positions = fopen("positions.txt", "a");
  83. velocities = fopen("velocities.txt", "a");
  84.  
  85. /* the phase point is set up so we can now start the loop. */
  86. int next_car;
  87. double k1, k2, k3, k4;
  88. double m1, m2, m3, m4;
  89. double velocity_orig;
  90. for (int i = 0; i < n_steps; i++) {
  91. /* print the timestep to file. */
  92. fprintf (positions, "%.6f ", (float)current_time);
  93. fprintf (velocities, "%.6f ", (float)current_time);
  94.  
  95. /* build the current net distance and approaching rate. */
  96. for (int i = 0; i < n_cars; i++) {
  97. /* print the positions and velocities to file. */
  98. fprintf(positions, "%.6f ", (float)cars[i].position_x);
  99. fprintf(velocities, "%.6f ", (float)cars[i].velocity_x);
  100.  
  101. /*
  102. * define the next car_t with periodic boundary conditions
  103. * so the first car_t in the loop is seen by the last.
  104. */
  105. next_car = (i + 1) % n_cars;
  106.  
  107. cars[i].net_distance = cars[next_car].position_x - cars[i].position_x - cars[next_car].vehicle_length;
  108.  
  109. /*
  110. * if the distance is less than 0, then the next car_t has
  111. * been moved across the periodic boundary.
  112. */
  113. if (cars[i].net_distance < 0)
  114. cars[i].net_distance += road_length;
  115.  
  116. cars[i].approaching_rate = cars[i].velocity_x - cars[next_car].velocity_x;
  117. }
  118.  
  119. /* begin runge-kutta order four. */
  120. for (int i = 0; i < n_cars; i++) {
  121. /*
  122. * store the original values of the velocity
  123. * so it can be modified from and restored
  124. * during the rk procedure. the positions do
  125. * do not appear in the derivatives and
  126. * therefore need not be treated here.
  127. */
  128. velocity_orig = cars[i].velocity_x;
  129.  
  130. k1 = position_derivative(cars[i]);
  131. m1 = velocity_derivative(cars[i]);
  132.  
  133. cars[i].velocity_x = velocity_orig + (0.5 * m1 * time_step);
  134.  
  135. k2 = position_derivative(cars[i]);
  136. m2 = velocity_derivative(cars[i]);
  137.  
  138. cars[i].velocity_x = velocity_orig + (0.5 * m2 * time_step);
  139.  
  140. k3 = position_derivative(cars[i]);
  141. m3 = velocity_derivative(cars[i]);
  142.  
  143. cars[i].velocity_x = velocity_orig + (m3 * time_step);
  144.  
  145. k4 = position_derivative(cars[i]);
  146. m4 = velocity_derivative(cars[i]);
  147.  
  148. /* finally update the variables. */
  149. current_time += time_step;
  150. cars[i].position_x += ((k1 + (2 * k2) + (2 * k3) + k4)) * (time_step / 6);
  151. cars[i].velocity_x = velocity_orig + ((m1 + (2 * m2) + (2 * m3) + m4)) * (time_step / 6);
  152.  
  153. /*
  154. * if the car_t has moved beyond the end of the road,
  155. * move it back to the beginning.
  156. */
  157.  
  158. if (cars[i].position_x > road_length)
  159. cars[i].position_x -= road_length;
  160. }
  161.  
  162. /* we're done with this step's output so print a new line in output files. */
  163. fprintf(positions, "\n");
  164. fprintf(velocities, "\n");
  165. }
  166.  
  167. /* close file pointers. */
  168. fclose(positions);
  169. fclose(velocities);
  170.  
  171. return 0;
  172. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement