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); } }
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 ()); } }
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 }
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); }
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); }
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); }
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); }
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); } }
virtual void Check_Output (Travel_Step &travel) { travel.Status (1); }