Beispiel #1
0
int Sim_Node_Process::Sum_Path (Sim_Dir_Ptr sim_dir_ptr, int lane, int cell, Travel_Step &step)
{
	int cells, num_cells, sum_speed, num_lanes, num_veh, best_weight, weight;
	int speed, max_cell, dir_index, traveler, from_lane, from_index, l, high, low;

	Dir_Data *dir_ptr;
	Sim_Plan_Ptr sim_plan_ptr;
	Sim_Leg_Ptr leg_ptr, next_ptr;
	Sim_Park_Ptr sim_park_ptr;
	Sim_Travel_Ptr sim_travel_ptr;

	//---- initial conditions ----

	num_cells = sim->Offset_Cell (sim->param.look_ahead);
	sum_speed = num_lanes = num_veh = 0;

	speed = step.sim_travel_ptr->Speed ();
	sim_plan_ptr = step.sim_travel_ptr->Get_Plan ();

	//---- get the plan data ----

	leg_ptr = step.sim_leg_ptr;
	next_ptr = sim_plan_ptr->Get_Next (leg_ptr);

	dir_index = leg_ptr->Index ();
	max_cell = sim_dir_ptr->Max_Cell ();

	if (next_ptr != 0 && next_ptr->Type () == PARKING_ID) {
		sim_park_ptr = &sim->sim_park_array [next_ptr->Index ()];

		if (sim_park_ptr->Type () != BOUNDARY) {
			if (sim_dir_ptr->Dir () == 0) {
				max_cell = sim->Offset_Cell (sim_park_ptr->Offset_AB ());
			} else {
				max_cell = sim->Offset_Cell (sim_park_ptr->Offset_BA ());
			}
		}
	}

	for (cells=1; cells <= num_cells; cells++) {
		cell++;

		//---- move forward ----

		if (cell > max_cell) {

			//---- set the exit speed ----

			if (leg_ptr->Max_Speed () < speed) {
				speed = leg_ptr->Max_Speed ();
			}
		
			//---- check the exit lane ----

			if (lane < leg_ptr->Out_Lane_Low ()) {
				num_lanes += leg_ptr->Out_Lane_Low () - lane;
				lane = leg_ptr->Out_Lane_Low ();
				speed = 0;
			} else if (lane > leg_ptr->Out_Lane_High ()) {
				num_lanes += lane - leg_ptr->Out_Lane_High ();
				lane = leg_ptr->Out_Lane_High ();
				speed = 0;
			}
			from_lane = lane;
			from_index = dir_index;

			if (next_ptr == 0 || next_ptr->Type () != DIR_ID) break;

			dir_index = next_ptr->Index ();

			sim_dir_ptr = &sim->sim_dir_array [dir_index];

			if (sim_dir_ptr->Method () < MESOSCOPIC) break;

			leg_ptr = next_ptr;

			//---- find the best connection ----

			lane = -1;
			best_weight = 0;

			low = leg_ptr->In_Lane_Low ();
			high = leg_ptr->In_Lane_High ();

			for (l=low; l < high; l++) {
				weight = 0;
				if (sim_dir_ptr->Thru_Link (l) == from_index && sim_dir_ptr->Thru_Lane (l) == from_lane) {
					weight += sim->param.connect_lane_weight;
				}
				if (Cell_Use (sim_dir_ptr, l, 0, step)) {
					weight += sim->param.lane_use_weight;
				}
				if (l >= leg_ptr->In_Best_Low () && l <= leg_ptr->In_Best_High ()) {
					weight += sim->param.connect_lane_weight;
				}

				if (weight > best_weight) {
					lane = l;
					best_weight = weight;
				}
			}
			if (lane < 0) break;
			cell = 0;

			next_ptr = sim_plan_ptr->Get_Next (leg_ptr);

			max_cell = sim_dir_ptr->Max_Cell ();

			if (next_ptr != 0 && next_ptr->Type () == PARKING_ID) {
				sim_park_ptr = &sim->sim_park_array [next_ptr->Index ()];

				if (sim_park_ptr->Type () != BOUNDARY) {
					if (sim_dir_ptr->Dir () == 0) {
						max_cell = sim->Offset_Cell (sim_park_ptr->Offset_AB ());
					} else {
						max_cell = sim->Offset_Cell (sim_park_ptr->Offset_BA ());
					}
				}
			}
		}

		//---- check the use restrictions ----

		if (!Cell_Use (sim_dir_ptr, lane, cell, step)) {
			if (lane > 0) {
				while (lane > 0) {
					num_lanes++;
					if (Cell_Use (sim_dir_ptr, --lane, cell, step)) break;
				}
			} else {
				while (lane < (sim_dir_ptr->Lanes () - 1)) {
					num_lanes++;
					if (Cell_Use (sim_dir_ptr, ++lane, cell, step)) break;
				}
			}
			speed = 0;

		} else {

			//---- check the cell availability -----

			traveler = sim_dir_ptr->Get (lane, cell);

			if (traveler == -1) {

				//---- pocket lane ----

				dir_ptr = &sim->dir_array [dir_index];

				if (lane <= dir_ptr->Left ()) {
					while (lane <= dir_ptr->Left ()) {
						num_lanes++;
						if (sim_dir_ptr->Get (++lane, cell) >= 0) break;
					}
				} else {
					while (lane >= (dir_ptr->Left () + dir_ptr->Lanes ())) {
						num_lanes++;
						if (sim_dir_ptr->Get (--lane, cell) >= 0) break;
					}
				}
				speed = 0;

			} else {

				//---- accelerate ----

				speed += step.veh_type_ptr->Max_Accel ();

				if (speed > step.veh_type_ptr->Max_Speed ()) {
					speed = step.veh_type_ptr->Max_Speed ();
				}
				if (speed > sim_dir_ptr->Speed ()) {
					speed = sim_dir_ptr->Speed ();
				}

				//---- check the vehicle speed ----

				traveler = abs (traveler);

				if (traveler > 1) {
					sim_travel_ptr = &sim->sim_travel_array [traveler];

					if (sim_travel_ptr->Speed () < speed) {
						speed = sim_travel_ptr->Speed ();
					}
					num_veh++;
				}
			}
		}
		sum_speed += speed - step.Delay ();
	}
	sim->Offset_Cell (sum_speed);
	sum_speed = DTOI (sum_speed * sim->param.time_factor - num_lanes * sim->param.lane_factor - num_veh * sim->param.veh_factor);

	return (sum_speed);	
}
Beispiel #2
0
bool Sim_Method::Cell_Use (Sim_Lane_Data *lane_ptr, int lane, int cell, Travel_Step &step, bool use_flag)
{
	int i, index, num, seed;
	Lane_Use_Data *use_ptr;
	Lane_Use_Period *period_ptr;
	Link_Dir_Data *use_index;

	int type = step.sim_traveler_ptr->Type ();
	int veh_type = step.sim_veh_ptr->Type ();
	Use_Type use = step.veh_type_ptr->Use ();

	step.Delay (0);

	if (use_flag) {
		if (use != BUS && use != HOV2 && use != HOV3 && use != HOV4) return (false);
		if (Use_Permission (lane_ptr->Use (), SOV)) return (false);
	}
	if (!Use_Permission (lane_ptr->Use (), use)) return (false);

	if (veh_type >= 0 && lane_ptr->Min_Veh_Type () >= 0) {
		if (lane_ptr->Type () == PROHIBIT) {
			if (veh_type >= lane_ptr->Min_Veh_Type () && veh_type <= lane_ptr->Max_Veh_Type ()) return (false);
		} else {
			if (veh_type < lane_ptr->Min_Veh_Type () || veh_type > lane_ptr->Max_Veh_Type ()) return (false);
		}
	}
	if (type > 0 && lane_ptr->Min_Traveler () > 0) {
		if (lane_ptr->Type () == PROHIBIT) {
			if (type >= lane_ptr->Min_Traveler () && type <= lane_ptr->Max_Traveler ()) return (false);
		} else {
			if (type < lane_ptr->Min_Traveler () || type > lane_ptr->Max_Traveler ()) return (false);
		}
	}
	index = lane_ptr->First_Use ();
	if (index < 0) return (true);

	period_ptr = &exe->use_period_array [index];

	num = period_ptr->Records ();
	index = period_ptr->Index ();

	for (i=0; i < num; i++, index++) {
		use_index = &exe->use_period_index [index];
		use_ptr = &exe->lane_use_array [use_index->Link ()];

		if (use_ptr->Offset () > 0 || use_ptr->Length () > 0) {
			int offset = cell * param.cell_size;

			if (use_ptr->Offset () > offset || offset > (use_ptr->Offset () + use_ptr->Length ())) continue;
		}
		if (use_ptr->Type () == REQUIRE) {
			if (!Use_Permission (use_ptr->Use (), use)) continue;
			if (veh_type >= 0 && use_ptr->Min_Veh_Type () >= 0) {
				if (veh_type < use_ptr->Min_Veh_Type () || veh_type > use_ptr->Max_Veh_Type ()) continue;
			}
			if (type > 0 && use_ptr->Min_Traveler () > 0) {
				if (type < use_ptr->Min_Traveler () || type > use_ptr->Max_Traveler ()) continue;
			}
			return (lane >= use_ptr->Low_Lane () && lane <= use_ptr->High_Lane ());
		} else {
			if (lane < use_ptr->Low_Lane () || lane > use_ptr->High_Lane ()) continue;

			if (use_ptr->Type () == PROHIBIT) {
				if (use_flag && !Use_Permission (use_ptr->Use (), SOV)) return (false);
				if (!Use_Permission (use_ptr->Use (), use)) continue;
				if (veh_type >= 0 && use_ptr->Min_Veh_Type () >= 0) {
					if (veh_type < use_ptr->Min_Veh_Type () || veh_type > use_ptr->Max_Veh_Type ()) continue;
				}
				if (type > 0 && use_ptr->Min_Traveler () > 0) {
					if (type < use_ptr->Min_Traveler () || type > use_ptr->Max_Traveler ()) continue;
				}
				return (false);
			} else if (use_ptr->Type () == LIMIT) {
				if (use_flag && Use_Permission (use_ptr->Use (), SOV)) return (false);
				if (!Use_Permission (use_ptr->Use (), use)) return (false);
				if (veh_type >= 0 && use_ptr->Min_Veh_Type () >= 0) {
					if (veh_type < use_ptr->Min_Veh_Type () || veh_type > use_ptr->Max_Veh_Type ()) return (false);
				}
				if (type > 0 && use_ptr->Min_Traveler () > 0) {
					if (type < use_ptr->Min_Traveler () || type > use_ptr->Max_Traveler ()) return (false);
				}
				return (true);
			} else if (use_ptr->Type () == APPLY) {
				if (!Use_Permission (use_ptr->Use (), use)) continue;
				if (veh_type >= 0 && use_ptr->Min_Veh_Type () >= 0) {
					if (veh_type < use_ptr->Min_Veh_Type () || veh_type > use_ptr->Max_Veh_Type ()) continue;
				}
				if (type >= 0 && use_ptr->Min_Traveler () > 0) {
					if (type < use_ptr->Min_Traveler () || type > use_ptr->Max_Traveler ()) continue;
				}
				if (use_ptr->Min_Delay () > 0 || use_ptr->Max_Delay () > 0) {
					if (use_ptr->Offset () > 0 || use_ptr->Length () > 0) {
						if (cell != (use_ptr->Offset () + (use_ptr->Length () / 2)) / param.cell_size) break;
					} else {
						if (cell != (int) (lane_ptr->size () / 2)) break;
					}
					int diff = 0;
					if (use_ptr->Max_Delay () > use_ptr->Min_Delay ()) {
						seed = abs (index + exe->Random_Seed () + step.Vehicle () + lane);
						diff = DTOI ((use_ptr->Max_Delay () - use_ptr->Min_Delay ()) * exe->random.Probability (seed));
					}
					step.Delay (use_ptr->Min_Delay () + diff);
				}
				break;
			}
		}
	}
	return (true);
}