void handle_update_request( Train_update_request *update_request, Train_status *train_status, Train_server_data *server_data ){ // What type of request is this? if ( update_request->update_type == MOVE_FREE_UPDATE ){ // The train has been ordered to move freely. // If there was a previous goal, remove it. initialize_goal( train_status ); // TODO: Make the sensor detective check all sensors -> We are assuming that there's only 1 train in the track. // Send the commands int cmd_type = update_request->cmd.cmd_type; switch( cmd_type ){ case TRAIN_CMD_TYPE: train_status->motion_data.original_train_speed = 0; train_status->motion_data.distance_type = LONG_DISTANCE; send_train_move_command( update_request->cmd.param, 0, train_status, server_data ); break; case REVERSE_CMD_TYPE: train_status->motion_data.original_train_speed = train_status->motion_data.train_speed; train_status->motion_data.distance_type = LONG_DISTANCE; send_train_move_command( TRAIN_STOP_CMD_SPEED, 0, train_status, server_data ); train_status->is_reversing = 1; break; default: // Should never get here bwassert( 0, "TRAIN_MOTION: update_train_status -> Invalid command type." ); break; } } else if ( update_request->update_type == CHANGE_GOAL_UPDATE ){ // There's a new goal. // 1. Erase previous goal information initialize_goal( train_status ); // 2. Get a new path // NOTE: For the edge we always consider straight line. If the user wants to move to a curve branch, // then he needs to give another landmark. train_status->current_goal.landmark = ( track_node * ) update_request->cmd.element_id; // CAREFUL!!! train_status->current_goal.offset = update_request->cmd.param; train_status->current_goal.edge = &( train_status->current_goal.landmark->edge[ DIR_AHEAD ] ); int path_found = request_new_path( train_status, server_data ); bwassert( path_found, "TRAIN_MOTION: Path couldn't be found" ); // 3. Now the train has a goal. Update the status accordingly. train_status->train_state = TRAIN_STATE_MOVE_TO_GOAL; } }
int track_train_short_distance( Train_status *train_status, Train_server_data *server_data ){ int continue_execution = 0; if ( train_status->motion_state == TRAIN_STILL ){ // For short distances the only important state is when the train is still. // We don't care about the other states because the distances are too small. if ( has_train_arrived( train_status ) ){ // The train has reached its destination // - Remove the current goal initialize_goal( train_status ); continue_execution = 1; } // Release all the reserved track; keep only the current size of the train. reserve_distance( 0, train_status, server_data ); } return continue_execution; }
void initialize_tactic_module() { initialize_goal(); initialize_proof_state(); initialize_expr_to_tactic(); initialize_apply_tactic(); initialize_rename_tactic(); initialize_intros_tactic(); initialize_trace_tactic(); initialize_exact_tactic(); initialize_unfold_tactic(); initialize_generalize_tactic(); initialize_whnf_tactic(); initialize_clear_tactic(); initialize_revert_tactic(); initialize_inversion_tactic(); initialize_assert_tactic(); initialize_class_instance_elaborator(); initialize_rewrite_tactic(); initialize_change_tactic(); initialize_check_expr_tactic(); }
void predict_train_movement( int current_time, Train_status *train_status, Train_server_data *server_data ){ // Initialization int cmd_delay, speed_to_use, distance_to_reserve, time_in_constant_speed; int is_distance_reserved, next_update_time, accurate_current_time ; // Is the train supposed to move? // - If not, there's no need to stay in this method. if ( train_status->train_state == TRAIN_STATE_MOVE_FREE ){ int original_speed = train_status->motion_data.original_train_speed; int curr_speed = train_status->motion_data.train_speed; if ( original_speed == curr_speed && curr_speed == 0 ) return; } // If the train is moving a short distance track it somewhere else if ( train_status->motion_data.distance_type == SHORT_DISTANCE ){ int continue_exec = track_train_short_distance( train_status, server_data ); if ( !continue_exec ) return; } // Determine what's going to happen in the future, and how to react to it. switch( train_status->motion_state ){ case TRAIN_STILL: // -- Initialization -- accurate_current_time = TimeInMs(); cmd_delay = accurate_current_time; // 1. DETERMINE DIRECTION // - Is the train facing at the right direction? if ( train_status->train_state == TRAIN_STATE_MOVE_FREE ){ if ( train_status->is_reversing ){ // TODO: Do we need to add a delay because of this movement? send_reverse_command( train_status, server_data ); } speed_to_use = train_status->motion_data.original_train_speed; } else if ( train_status->train_state == TRAIN_STATE_MOVE_TO_GOAL ){ if ( has_train_arrived( train_status ) ){ // The train has reached its destination // - Remove the current goal initialize_goal( train_status ); // TODO: Remove the sensor tracking of this part of the track break; } // Does the train need to reverse? if ( requires_reversing( train_status ) ){ train_status->is_reversing = 1; cmd_delay += get_reverse_delay_time( server_data ); send_reverse_command( train_status, server_data ); // NOTE: We calculate the route again in case the "extra" space // used for reverse causes problems. clear_train_motion_data( train_status ); int path_found = request_new_path( train_status, server_data ); bwassert( path_found, "TRAIN_MOTION: Path couldn't be found" ); } // Calculate the next "straight" movement speed_to_use = calculate_speed_to_use( train_status, &server_data->calibration_data ); } if ( train_status->motion_data.distance_type == SHORT_DISTANCE ){ // Since the behavior of short distances is different, they are handled in a different function. start_short_distance_movement( speed_to_use, train_status, server_data ); } else{ // 2. RESERVATION // - The train is going to move, and it's already facing the right direction. // - How far should we reserve? distance_to_reserve = //get_train_acceleration_distance( speed_to_use, server_data ) + // TODO: Make sure we don't need this part -> I don't think we need it. get_train_stopping_distance( speed_to_use, server_data ) + get_reservation_distance_buffer( server_data ); is_distance_reserved = reserve_distance( distance_to_reserve, train_status, server_data ); // 3. START MOVEMENT // - If the reservation was successful, are there any switches that need to be moved? // - If the reservation was successful, start moving if ( is_distance_reserved ){ if ( train_status->train_state == TRAIN_STATE_MOVE_TO_GOAL ){ // Move switches within that distance int num_sw_changed = check_next_sw_pos( distance_to_reserve, train_status, server_data ); if ( num_sw_changed ){ //cmd_delay = current_time + get_sw_delay_time( server_data ); } // Add the sensors to attribution list. add_sensors_attrib_list( distance_to_reserve, train_status, server_data ); } // Start moving //bwprintf( COM2, "Starting Moving: [ train_id: %d speed: %d dir: %d ]\n", // train_status->train_id, speed_to_use, train_status->train_direction ); send_train_move_command( speed_to_use, cmd_delay, train_status, server_data ); } } break; case TRAIN_ACCELERATING: case TRAIN_CONSTANT_SPEED: // When will the next update be done? next_update_time = get_next_update_time( current_time ); // 1. Calculate distance to reserve // -- Get the basic data int time_speed_change = train_status->time_speed_change; int time_to_reach_constant_sp = get_time_to_constant_speed( train_status, server_data ); int time_to_start_deacceleration = get_time_to_start_deaccelerating( train_status, server_data ); time_in_constant_speed = time_to_start_deacceleration - time_to_reach_constant_sp; // -- The distance to reserve regardless of the amount of constant data traveled distance_to_reserve = get_train_stopping_distance( train_status->motion_data.train_speed, server_data ) + get_reservation_distance_buffer( server_data ); if ( time_speed_change + time_to_reach_constant_sp < next_update_time ){ // The train will move some time at constant speed. // -- How much time will the train move at constant speed before the next update? int init_time, end_time, time_const_speed_before_update; //int time_const_speed_before_update; if ( train_status->train_state == TRAIN_STATE_MOVE_TO_GOAL ){ // Check when the constant speed was reached in this update interval if( time_speed_change + time_to_reach_constant_sp <= current_time ) init_time = current_time; else init_time = time_speed_change + time_to_reach_constant_sp; // Check when to stop counting constant speed in this update interval if ( time_speed_change + time_to_start_deacceleration < next_update_time ) end_time = time_speed_change + time_to_start_deacceleration; else end_time = next_update_time; time_const_speed_before_update = end_time - init_time; } else{ time_const_speed_before_update = current_time - next_update_time; } // -- The distance traveled during constant speed before the next update also needs to be reserved. int train_speed = train_status->motion_data.train_speed; int distance_constant_speed = round_decimal_up( get_distance_in_constant_speed( time_const_speed_before_update, train_speed, server_data ) ); distance_to_reserve += distance_constant_speed; bwdebug( DBG_USR, TRAIN_SRV_DEBUG_AREA, "TRAIN_MOTION: Train traveled at constant speed. [ train_id: %d distance_traveled: %d ]", train_status->train_id, distance_constant_speed ); } // 2. Reserve the distance //bwprintf( COM2, "[ RESERVATION -> Reserved_distance: %d ]\n", distance_to_reserve ); is_distance_reserved = reserve_distance( distance_to_reserve, train_status, server_data ); // 3. Prepare everything in the reserved distance for the train movement if ( is_distance_reserved ){ // Check if there are switches to move in the reserved distance. check_next_sw_pos( distance_to_reserve, train_status, server_data ); // Does that train need to start de-accelerating? int temp_time = time_speed_change + time_to_start_deacceleration; ////bwprintf( COM2, "DEACCELERATE -> CURRENT_TIME: %d NEXT_UPD_TIME: %d TIME_SP_CHANGE: %d TIME_TO_DEACC: %d\n", // current_time, next_update_time, time_speed_change, time_to_start_deacceleration ); if ( temp_time >= current_time && temp_time < next_update_time ){ send_train_move_command( TRAIN_STOP_CMD_SPEED, temp_time, train_status, server_data ); } // Add sensors to attribution list add_sensors_attrib_list( distance_to_reserve, train_status, server_data ); } else{ // The new distance couldn't be reserved. STOP RIGHT AWAY!!! bwdebug( DBG_USR, TRAIN_SRV_DEBUG_AREA, "TRAIN_MOTION: Couldn't reserve distance. Stopping!! [ train_id: %d distance_requested: %d ]", train_status->train_id, distance_to_reserve ); send_train_move_command( TRAIN_STOP_CMD_SPEED, 0, train_status, server_data ); } break; case TRAIN_DEACCELERATING: bwdebug( DBG_USR, TRAIN_SRV_DEBUG_AREA, "TRAIN_MOTION: Deaccelerating. [ train_id: %d ]", train_status->train_id ); distance_to_reserve = 0; int distance_since_deacceleration = train_status->distance_since_speed_change - train_status->distance_before_deacceleration; distance_to_reserve = get_train_stopping_distance( train_status->motion_data.train_speed, server_data) - distance_since_deacceleration; // The train doesn't care if it gets the reserved distance or not; it should but it's already stopping anyway reserve_distance( distance_to_reserve, train_status, server_data ); // Add sensors to attribution list add_sensors_attrib_list( distance_to_reserve, train_status, server_data ); break; } }