Пример #1
0
void Simulator_Base::Check_Output (Travel_Step &step)
{
	if (step.Vehicle () < 0) return;

	//---- link delay processing ----

	if (link_delay_output.Output_Flag ()) {
		link_delay_output.Summarize (step);
	}

	//----- performance processing -----

	if (performance_output.Output_Flag ()) {
		performance_output.Summarize (step);
	}

	//----- turn volume processing -----

	if (turn_vol_output.Output_Flag ()) {
		turn_vol_output.Summarize (step);
	}

	//----- occupancy processing -----

	if (occupancy_output.Output_Flag ()) {
		occupancy_output.Summarize (step);
	}
}
Пример #2
0
bool Simulator_Service::Output_Step (Travel_Step &step)
{
	bool new_plan, problem_flag, no_veh_flag;

	Sim_Plan_Ptr sim_plan_ptr;
	Sim_Dir_Ptr sim_dir_ptr;
	Sim_Veh_Data sim_veh;
	Sim_Veh_Ptr sim_veh_ptr = 0;
	Problem_Data problem_data;
	Sim_Leg_Ptr sim_leg_ptr;

	//---- check the traveler data ----

	if (step.sim_travel_ptr == 0) {
		if (step.Traveler () < 2) return (false);

		step.sim_travel_ptr = &sim->sim_travel_array [step.Traveler ()];
	}

	//---- mark the traveler as processed in this time step ----

	step.sim_travel_ptr->Step_Code (sim->Step_Code ());

	if (step.sim_plan_ptr == 0) {
		step.sim_plan_ptr = step.sim_travel_ptr->Get_Plan ();
	}
	sim_plan_ptr = step.sim_plan_ptr;
#ifdef CHECK
	if (sim_plan_ptr == 0) sim->Error (String ("Simulator_Service::Output_Step: sim_plan_ptr, Household=%d, Problem=%d") % step.sim_travel_ptr->Household () % step.Problem ());
#endif

	if (step.sim_leg_ptr == 0) {
		step.sim_leg_ptr = sim_plan_ptr->Get_Leg ();
	}
	sim_leg_ptr = step.sim_leg_ptr;
	no_veh_flag = ((sim_leg_ptr == 0 && step.sim_travel_ptr->Vehicle () == 0) || 
		(sim_leg_ptr != 0 && sim_leg_ptr->Mode () != DRIVE_MODE && sim_leg_ptr->Type () != STOP_ID));

	new_plan = false;

	//---- process the problem message ----

	if (step.Problem () > 0) {
		problem_flag = (!sim->select_problems || sim->problem_range.In_Range (step.Problem ()));

		//---- check for lost problems ----

		if (step.Problem () == DEPARTURE_PROBLEM || step.Problem () == ARRIVAL_PROBLEM || step.Problem () == WAIT_PROBLEM || 
			step.Problem () == LOAD_PROBLEM || step.Problem () == PATH_PROBLEM) {

			if (step.sim_travel_ptr->Person () == 0) {
				stats.num_run_lost++;
			} else if (!no_veh_flag) {
				stats.num_veh_lost++;

				//---- check the lost vehicle event ----

				if (step.sim_travel_ptr->Vehicle () > 0) {
					step.Event_Type (VEH_LOST_EVENT);
					sim->sim_output_step.Event_Check (step);
				}
			}
			new_plan = true;
		}

		//---- count problems ----

		if (new_plan || problem_flag || sim->param.count_warnings) {
			step.sim_travel_ptr->Problem (1);
			sim->Set_Problem ((Problem_Type) step.Problem ());
		}

		//---- write selected problems -----

		if (problem_flag && sim->param.problem_flag && sim_plan_ptr != 0) {
			if ((int) step.size () > 0) {
				sim_veh = step.back ();
			} else if (!no_veh_flag) {
#ifdef CHECK
				if (step.sim_travel_ptr->Vehicle () < 1) sim->Error ("Simulator_Service::Output_Step: Vehicle");
#endif
				sim_veh = sim->sim_veh_array [step.sim_travel_ptr->Vehicle ()];
			}
			problem_data.Household (step.sim_travel_ptr->Household ());
			problem_data.Person (step.sim_travel_ptr->Person ());
			problem_data.Tour (sim_plan_ptr->Tour ());
			problem_data.Trip (sim_plan_ptr->Trip ());

			problem_data.Start (sim_plan_ptr->Start ());
			problem_data.End (sim_plan_ptr->End ());
			problem_data.Duration (sim_plan_ptr->Activity ());

			problem_data.Origin (sim_plan_ptr->Origin ());
			problem_data.Destination (sim_plan_ptr->Destination ());

			problem_data.Purpose (sim_plan_ptr->Purpose ());
			problem_data.Mode (sim_plan_ptr->Mode ());
			problem_data.Constraint (sim_plan_ptr->Constraint ());
			problem_data.Priority (sim_plan_ptr->Priority ());
			problem_data.Vehicle (sim_plan_ptr->Vehicle ());

			problem_data.Type (sim_plan_ptr->Type ());
			problem_data.Problem (step.Problem ());
			problem_data.Time (sim->time_step);

			problem_data.Dir_Index (sim_veh.link);
			problem_data.Lane (sim_veh.lane);
		
			if (sim_veh.link >= 0) {
				sim_dir_ptr = &sim->sim_dir_array [sim_veh.link];
				if (sim_veh.offset > sim_dir_ptr->Length ()) sim_veh.offset = sim_dir_ptr->Length ();
			}
			problem_data.Offset (sim_veh.offset);
			problem_data.Route (-1);

			if (step.sim_travel_ptr->Person () == 0) {
				int route = sim->line_array.Route (step.sim_travel_ptr->Household ());

				Int_Map_Itr map_itr = sim->line_map.find (route);
				if (map_itr != sim->line_map.end ()) {
					problem_data.Route (map_itr->second);
				}
			} else if (no_veh_flag && sim_leg_ptr != 0 && sim_leg_ptr->Type () == ROUTE_ID) {
				Int_Map_Itr map_itr = sim->line_map.find (sim_leg_ptr->Index ());
				if (map_itr != sim->line_map.end ()) {
					problem_data.Route (map_itr->second);
				}
			}
			sim->sim_output_step.Output_Problem (problem_data);
		}
	}
	step.Problem (0);

	//---- process vehicle movement ----

	if (step.size () > 0 && !no_veh_flag) {
		sim->sim_output_step.Output_Check (step);
	}
	if (sim_plan_ptr->First_Leg () < 0) {
		new_plan = true;
	}

	//---- check the vehicle data ----

	if (!no_veh_flag) {
		if (step.sim_veh_ptr == 0) {
#ifdef CHECK
			if (step.sim_travel_ptr->Vehicle () < 1) sim->Error (String ("Simulator_Service::Output_Step: Vehicle %d, Household=%d") % step.sim_travel_ptr->Vehicle () % step.sim_travel_ptr->Household ());
#endif
			step.sim_veh_ptr = &sim->sim_veh_array [step.sim_travel_ptr->Vehicle ()];
#ifdef CHECK
		} else {
			sim_veh_ptr = &sim->sim_veh_array [step.sim_travel_ptr->Vehicle ()];

			if (sim_veh_ptr != step.sim_veh_ptr) {
				sim->Error ("Simulator_Service::Output_Step: Vehicle Pointer");
			}
#endif
		}
		sim_veh_ptr = step.sim_veh_ptr;
#ifdef CHECK
		if (sim_veh_ptr == 0) sim->Error ("Simulator_Service::Output_Step: sim_veh_ptr");
#endif

		//---- park the vehicle ----

		if (new_plan || sim_veh_ptr->Parked ()) {
			step.veh_type_ptr = &sim->veh_type_array [sim_plan_ptr->Veh_Type ()];
			Remove_Vehicle (step);
		}

#ifdef THREADS

		if (Num_Threads () > 0 && (int) step.size () > 1) {
			int index = step.Dir_Index ();
			Sim_Veh_Itr sim_veh_itr;
#ifdef CHECK
			if (index < 0 || index > (int) sim->sim_dir_array.size ()) sim->Error (String ("Output_Step::Unlock Index=%d vs %d") % index % sim->sim_dir_array.size ());
#endif
			//---- release link locks ----

			for (sim_veh_itr = step.begin (); sim_veh_itr != step.end (); sim_veh_itr++) {
				if (sim_veh_itr->link != index && sim_veh_itr->link >= 0 && sim_veh_itr->lane > -1) {
					index = sim_veh_itr->link;
#ifdef CHECK
					if (index < 0 || index > (int) sim->sim_dir_array.size ()) sim->Error (String ("Output_Step::Unlock Index=%d vs %d") % index % sim->sim_dir_array.size ());
#endif
					sim_dir_ptr = &sim->sim_dir_array [index];
#ifdef CHECK
					if (step.Process_ID () > 0 && sim_dir_ptr->Lock () != step.Process_ID ()) sim->Error (String ("Output_Step::Unlock (% vs %d), Index=%d, dir=%d") % sim_dir_ptr->Lock () % step.Process_ID () % index % sim_dir_ptr->Dir ());
#endif
					sim->sim_dir_array.UnLock (sim_dir_ptr, step.Process_ID ());
				}
			}
		}
#endif
	}

	//---- move to the next plan ----

	if (new_plan) {
		if (!no_veh_flag) sim_veh_ptr->Parked (true);


		step.sim_travel_ptr->Vehicle (0);
		step.sim_travel_ptr->Next_Load (-1);

		if (step.sim_travel_ptr->Person () > 0) {
			step.sim_travel_ptr->Status (NOT_ACTIVE);
			step.sim_travel_ptr->Next_Event (sim->time_step + sim_plan_ptr->Activity ());
		} else {
			step.sim_travel_ptr->Status (OFF_NET_END);
			step.sim_travel_ptr->Next_Event (sim->param.end_time_step);
		}
		if (!step.sim_travel_ptr->Next_Plan ()) return (false);

		step.sim_plan_ptr = step.sim_travel_ptr->Get_Plan ();
		
		if (step.sim_plan_ptr->Start () > step.sim_travel_ptr->Next_Event ()) {
			step.sim_travel_ptr->Next_Event (step.sim_plan_ptr->Start ());
		}
		return (true);
	}
	if (no_veh_flag) {
		step.sim_travel_ptr->Status (OFF_NET_MOVE);
		return (true);
	} else {
		if (sim_veh_ptr->Parked ()) {
			step.sim_travel_ptr->Status (OFF_NET_MOVE);
		} else if (step.sim_travel_ptr->Status () == ON_OFF_DRIVE) {
			step.sim_travel_ptr->Status (OFF_NET_DRIVE);
		}
		return (!sim_veh_ptr->Parked ());
	}
}
Пример #3
0
bool Sim_Method::Check_Queue (Travel_Step &step)
{
    int dir_index, lane, cell, to_cell, control, end_cell, first_cell, last_cell, max_cell, mid_cell;
    int speed, max_speed, pce, index, veh_type;
    double capacity;
    bool next_flag, restricted_flag, park_flag, method_flag = false;
    Use_Type use;

    Sim_Veh_Ptr sim_veh_ptr;
    Sim_Dir_Ptr sim_dir_ptr, next_dir_ptr = 0;
    Sim_Cap_Ptr sim_cap_ptr, next_cap_ptr = 0;
    Sim_Lane_Ptr next_lane_ptr;
    Cell_Data cell_rec;
    Sim_Plan_Ptr plan_ptr;
    Sim_Leg_Itr leg_itr, next_leg;
    Connect_Data *connect_ptr;
    Sim_Park_Ptr sim_park_ptr;
    Dir_Data *dir_ptr;
    Turn_Pen_Data *turn_ptr;

    //---- get the current location ----

    if (step.size () > 0) {
        cell_rec = step.back ();
    } else {
        cell_rec = step.sim_veh_ptr->front ();
    }
    dir_index = cell_rec.Index ();
    cell = cell_rec.Cell ();

    if (dir_index == step.Dir_Index ()) {
        if (step.sim_dir_ptr == 0) {
            step.sim_dir_ptr = &exe->sim_dir_array [dir_index];
        }
        sim_dir_ptr = step.sim_dir_ptr;
    } else {
        sim_dir_ptr = &exe->sim_dir_array [dir_index];
    }
    if (!sim_dir_ptr->Active ()) return (step.size () > 0);

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

    //---- find the end of the queue ----

    sim_cap_ptr = sim_dir_ptr->Sim_Cap ();

    capacity = sim_cap_ptr->High_Capacity () + sim_cap_ptr->Low_Capacity ();
    max_cell = (int) (sim_dir_ptr->Cells () * (1.0 - (step.Position () + 1) / capacity));

    pce = (int) step.sim_veh_ptr->size ();

    //---- calculate the maximum move ----

    max_speed = step.sim_veh_ptr->Speed () + step.veh_type_ptr->Max_Accel ();

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

    //---- apply random slow down ----

    if (max_speed > 0 && step.sim_veh_ptr->Priority () < 1 && param.slow_down_flag) {
        double slow_down = param.slow_down_prob [sim_dir_ptr->Type ()];
        if (param.traveler_flag) slow_down *= param.traveler_fac.Best (step.sim_traveler_ptr->Type ());

        if (slow_down > step.sim_traveler_ptr->random.Probability ()) {
            double percent = param.slow_down_percent [sim_dir_ptr->Type ()];
            if (param.traveler_flag) percent *= param.traveler_fac.Best (step.sim_traveler_ptr->Type ());

            if (percent > 0.0) {
                double spd = max_speed * percent;
                int slow_down = (int) spd;
                spd -= slow_down;

                if (spd > 0.0 && spd > step.sim_traveler_ptr->random.Probability ()) slow_down++;

                max_speed -= slow_down;
                if (slow_down > 0) {
                    stats.num_slow_down++;
#ifdef DEBUG_KEYS
                    if (exe->debug) MAIN_LOCK exe->Write (0, " slowdown=") << slow_down;
                    END_LOCK
#endif
                }
Пример #4
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);	
}
Пример #5
0
bool Sim_Method::Cell_Use (Travel_Step &step)
{
	int lane, lanes, cell;

	Sim_Dir_Ptr sim_dir_ptr;
	Sim_Lane_Ptr lane_ptr = 0;
	
	Cell_Data cell_rec = step.sim_veh_ptr->front ();

	if (cell_rec.Index () == step.Dir_Index ()) {
		if (step.sim_dir_ptr == 0) {
			step.sim_dir_ptr = &exe->sim_dir_array [cell_rec.Index ()];
		}
		sim_dir_ptr = step.sim_dir_ptr;
	} else {
		sim_dir_ptr = &exe->sim_dir_array [cell_rec.Index ()];
	}
	if (sim_dir_ptr->Method () != MESOSCOPIC) return (true);

	lanes = sim_dir_ptr->Lanes ();
	cell = cell_rec.Cell ();

	for (lane = 0; lane < lanes; lane++) {
		lane_ptr = sim_dir_ptr->Lane (lane);

		if (Cell_Use (lane_ptr, lane, cell, step)) return (true);
	}
	Dtime max_time = exe->step + param.max_wait_time;

	if (use_update_time < max_time) {
		int i, index, num;
		Lane_Use_Data *use_ptr;
		Lane_Use_Period *period_ptr;
		Link_Dir_Data *use_index;

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

		Dir_Data *dir_ptr = &exe->dir_array [cell_rec.Index ()];

		index = dir_ptr->First_Lane_Use ();
		if (index < 0) goto use_error;

		for (period_ptr = &exe->use_period_array [index]; ; period_ptr = &exe->use_period_array [++index]) {
			if (period_ptr->Start () >= use_update_time && period_ptr->Start () <= max_time) break;
			if (period_ptr->Periods () == 0) goto use_error;
		}
		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 () == PROHIBIT) {
				if (!Use_Permission (use_ptr->Use (), use)) {
					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 ()) {
							if (type > 0 && use_ptr->Min_Traveler () > 0) {
								if (type < use_ptr->Min_Traveler () || type > use_ptr->Max_Traveler ()) return (true);
							} else {
								return (true);
							}
						}
					} else if (type > 0 && use_ptr->Min_Traveler () > 0) {
						if (type < use_ptr->Min_Traveler () || type > use_ptr->Max_Traveler ()) return (true);
					} else {
						return (true);
					}
				}
			} else {
				if (Use_Permission (use_ptr->Use (), use)) {
					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 ()) {
							if (type > 0 && use_ptr->Min_Traveler () > 0) {
								if (type >= use_ptr->Min_Traveler () && type <= use_ptr->Max_Traveler ()) return (true);
							} else {
								return (true);
							}
						}
					} else if (type > 0 && use_ptr->Min_Traveler () > 0) {
						if (type >= use_ptr->Min_Traveler () && type <= use_ptr->Max_Traveler ()) return (true);
					} else {
						return (true);
					}
				}
			}
		}
	}
use_error:
	step.Problem (USE_PROBLEM);
	step.Status (1);
	return (false);
}
Пример #6
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);
}
Пример #7
0
bool Sim_Node_Process::Load_Vehicle (int traveler)
{
	int lane, cell, subarea, dir_index, offset;
	bool loaded, type_flag, bound_flag, side_flag;
	Dtime time;
	
	Travel_Step step;

	Sim_Travel_Ptr sim_travel_ptr;
	Sim_Plan_Ptr sim_plan_ptr;
	Sim_Leg_Ptr leg_ptr, next_leg;
	Sim_Dir_Ptr sim_dir_ptr;
	Sim_Park_Ptr sim_park_ptr;
	Sim_Stop_Ptr sim_stop_ptr;
	Veh_Type_Data *veh_type_ptr;
	Sim_Veh_Data veh_cell, *sim_veh_ptr;

	subarea = 0;

	//---- build the travel step ----

	step.Process_ID (ID ());
	step.Traveler (traveler);
	sim_travel_ptr = &sim->sim_travel_array [traveler];

	sim_plan_ptr = sim_travel_ptr->Get_Plan ();
	if (sim_plan_ptr == 0) return (false);

	step.sim_travel_ptr = sim_travel_ptr;

	leg_ptr = sim_plan_ptr->Get_Leg ();
	if (leg_ptr == 0) return (false);

	type_flag = (sim_travel_ptr->Status () == OFF_ON_DRIVE);

	if (type_flag) {
		next_leg = leg_ptr;
	} else {
		next_leg = sim_plan_ptr->Get_Next (leg_ptr);
	}
	if (next_leg == 0) return (false);

	if (next_leg->Type () != DIR_ID) goto access_problem;

	dir_index = next_leg->Index ();
	step.Dir_Index (dir_index);
	step.sim_dir_ptr = sim_dir_ptr = &sim->sim_dir_array [dir_index];

	//---- locate the load point ----

	if (type_flag) {

		//---- external link load ----

		offset = 0;
		bound_flag = true;
		side_flag = (sim_travel_ptr->random.Probability () >= 0.5);

	} else {

		//---- transit loading ----

		if (sim_travel_ptr->Person () == 0) {
			if (leg_ptr->Type () != STOP_ID) goto access_problem;

			sim_stop_ptr = &sim->sim_stop_array [leg_ptr->Index ()];

			bound_flag = false;
			side_flag = true;
			offset = sim_stop_ptr->Offset ();

		} else {	//---- parking lot load ----

			if (leg_ptr->Type () != PARKING_ID) goto access_problem;

			sim_park_ptr = &sim->sim_park_array [leg_ptr->Index ()];

			bound_flag = (sim_park_ptr->Type () == BOUNDARY);

			if (bound_flag) {
				side_flag = (sim_travel_ptr->random.Probability () >= 0.5);
			} else {
				side_flag = (sim_park_ptr->Dir () == sim_dir_ptr->Dir ());
			}
			if (sim_dir_ptr->Dir () == 0) {
				offset = sim_park_ptr->Offset_AB ();
			} else {
				offset = sim_park_ptr->Offset_BA ();
			}
		}
	}

	//---- set vehicle type attributes ----
	
	step.veh_type_ptr = veh_type_ptr = &sim->veh_type_array [sim_plan_ptr->Veh_Type ()];

	//---- set the access point ----

	loaded = false;
	lane = 0;
	cell = sim->Offset_Cell (offset);

	//---- load from the right ----

	if (side_flag) {

		//---- try to load onto the best lanes ----

		for (lane = next_leg->In_Best_High (); lane >= next_leg->In_Best_Low (); lane--) {
			loaded = Check_Cell (sim_dir_ptr, lane, cell, step);
			if (loaded) break;
		}
		if (!loaded) {

			//---- try to load on the permitted lanes ----

			for (lane = next_leg->In_Lane_High (); lane > next_leg->In_Best_High (); lane--) {
				loaded = Check_Cell (sim_dir_ptr, lane, cell, step);
				if (loaded) break;
			}
			if (!loaded) {
				for (lane = next_leg->In_Best_Low ()-1; lane >= next_leg->In_Lane_Low (); lane--) {
					loaded = Check_Cell (sim_dir_ptr, lane, cell, step);
					if (loaded) break;
				}
			}
		}

	} else {	//---- load from the left ----

		//---- try to load onto the best lanes ----

		for (lane = next_leg->In_Best_Low (); lane <= next_leg->In_Best_High (); lane++) {
			loaded = Check_Cell (sim_dir_ptr, lane, cell, step);
			if (loaded) break;
		}
		if (!loaded) {

			//---- try to load on the permitted lanes ----

			for (lane = next_leg->In_Lane_Low (); lane < next_leg->In_Best_Low (); lane++) {
				loaded = Check_Cell (sim_dir_ptr, lane, cell, step);
				if (loaded) break;
			}
			if (!loaded) {
				for (lane = next_leg->In_Best_High ()+1; lane <= next_leg->In_Lane_High (); lane++) {
					loaded = Check_Cell (sim_dir_ptr, lane, cell, step);
					if (loaded) break;
				}
			}
		}
	}
	if (!loaded) {
		if (sim_travel_ptr->Wait () > sim->param.min_load_time && sim_dir_ptr->Load_Cell () < 0) {
			sim_dir_ptr->Load_Cell (cell);
		}
		return (false);
	}

	//---- put the vehicle on the network ----

	step.sim_veh_ptr = sim_veh_ptr = &sim->sim_veh_array [sim_travel_ptr->Vehicle ()];

	sim_veh_ptr->Clear ();

	step.push_back (*sim_veh_ptr);

	sim_veh_ptr->Location (dir_index, lane, offset);

	if (bound_flag) {
		sim_travel_ptr->Speed (veh_type_ptr->Max_Speed ());
	} else {
		sim_travel_ptr->Speed (veh_type_ptr->Max_Accel ());
	}
	if (sim_travel_ptr->Speed () > sim_dir_ptr->Speed ()) {
		sim_travel_ptr->Speed (sim_dir_ptr->Speed ());
	}
	sim_travel_ptr->Wait (0);
	sim_travel_ptr->Priority (0);
	sim_travel_ptr->Step_Code (sim->Step_Code ());

	sim_dir_ptr->Add (lane, cell, traveler);

	//---- record the load event ----

	if (!type_flag) {
		sim_plan_ptr->Next_Leg ();

		if (sim_travel_ptr->Person () == 0) {
			stats.num_run_start++;
		} else {
			stats.num_veh_start++;

			//---- output vehicle start event ----

			step.Event_Type (VEH_START_EVENT);
			sim->sim_output_step.Event_Check (step);
		}
	}
	sim_travel_ptr->Next_Event (time);
	step.sim_travel_ptr->Status (ON_NET_DRIVE);

	//---- try to move forward ---

	Move_Vehicle (step);
	return (true);

access_problem:
	step.Problem (ACCESS_PROBLEM);
	sim->Output_Step (step);
	return (false);
}
Пример #8
0
bool Sim_Method::Output_Step (Travel_Step &step)
{
	int cell_offset, index, cell, lane, to_index, to_cell, to_lane, last_index, pce;
	int first_cell, last_cell, to_part, from_index;
	bool reload_flag, bound_flag, remove_flag = false;
	bool transfer_flag = false;

	Sim_Plan_Ptr plan_ptr;
	Sim_Leg_Itr leg_itr;
	Sim_Dir_Ptr sim_dir_ptr;
	Sim_Cap_Ptr sim_cap_ptr = 0;
	Sim_Veh_Ptr sim_veh_ptr;
	Cell_Itr cell_itr, veh_cell_itr, end_itr;
	Problem_Data problem_data;

	if (step.Vehicle () >= 0 && step.sim_veh_ptr == 0) {
		step.sim_veh_ptr = exe->sim_veh_array [step.Vehicle ()];
	}
	plan_ptr = step.sim_traveler_ptr->plan_ptr;

	//---- check for lost problems ----

	if (step.Status () == 1 || step.Problem () == DEPARTURE_PROBLEM || step.Problem () == ARRIVAL_PROBLEM) {
		if (plan_ptr->Person () == 0) {
			stats.num_run_lost++;
		} else {
			stats.num_veh_lost++;

			//---- check the lost vehicle event ----

			if (step.sim_veh_ptr != 0) {
				if (exe->Check_Event (VEH_LOST_EVENT, plan_ptr->Mode (), subarea)) {
					Event_Data event_data;

					event_data.Household (plan_ptr->Household ());
					event_data.Person (plan_ptr->Person ());
					event_data.Tour (plan_ptr->Tour ());
					event_data.Trip (plan_ptr->Trip ());
					event_data.Mode (plan_ptr->Mode ());

					if (step.Problem () == ARRIVAL_PROBLEM) {
						event_data.Schedule (plan_ptr->Arrive ());
					} else if (step.Problem () == DEPARTURE_PROBLEM) {
						event_data.Schedule (plan_ptr->Depart ());
					} else {
						event_data.Schedule (plan_ptr->Schedule ());
					}
					event_data.Actual (exe->step);
					event_data.Event (VEH_LOST_EVENT);

					veh_cell_itr = step.sim_veh_ptr->begin ();
					veh_cell_itr->Location (&to_index, &to_lane, &to_cell);

					event_data.Dir_Index (to_index);

					if (to_index >= 0 || to_cell > 0) {
						cell_offset = to_cell * param.cell_size + (param.cell_size >> 1);

						event_data.Offset (UnRound (cell_offset));
					} else {
						event_data.Offset (0);
					}
					event_data.Lane (to_lane);
					event_data.Route (-1);

					exe->Output_Event (event_data);
				}
			}
Пример #9
0
	virtual void Check_Output (Travel_Step &travel)      { travel.Status (1); }