...
Code Block | ||||
---|---|---|---|---|
| ||||
// // Structure of a train controller based on test case 2 // scchart Test2 "Test of IC_JCT" { // Set of request variables for all tracks for 11 trains bool IC_JCT_0_req[11], IC_LN_0_req[11], IC_LN_1_req[11], IC_LN_2_req[11]; bool IC_LN_3_req[11], IC_LN_4_req[11], IC_LN_5_req[11], IC_ST_0_req[11]; bool IC_ST_1_req[11], IC_ST_2_req[11], IC_ST_3_req[11], IC_ST_4_req[11]; bool IO_LN_0_req[11], IO_LN_1_req[11], IO_LN_2_req[11], KH_LN_0_req[11]; bool KH_LN_1_req[11], KH_LN_2_req[11], KH_LN_3_req[11], KH_LN_4_req[11]; bool KH_LN_5_req[11], KH_LN_6_req[11], KH_LN_7_req[11], KH_LN_8_req[11]; bool KH_ST_0_req[11], KH_ST_1_req[11], KH_ST_2_req[11], KH_ST_3_req[11]; bool KH_ST_4_req[11], KH_ST_5_req[11], KH_ST_6_req[11], KIO_LN_0_req[11]; bool KIO_LN_1_req[11], OC_JCT_0_req[11], OC_LN_0_req[11], OC_LN_1_req[11]; bool OC_LN_2_req[11], OC_LN_3_req[11], OC_LN_4_req[11], OC_LN_5_req[11]; bool OC_ST_0_req[11], OC_ST_1_req[11], OC_ST_2_req[11], OC_ST_3_req[11]; bool OC_ST_4_req[11], OI_LN_0_req[11], OI_LN_1_req[11], OI_LN_2_req[11]; // Set of permission variables for all tracks bool bool req_in_R, req_out_R, req_in_L, req_out_L, perm_in_R, perm_out_R, perm_in_L, perm_out_L;; // Set of permission variables for all tracks int IC_JCT_0_perm, IC_LN_0_perm, IC_LN_1_perm, IC_LN_2_perm; int IC_LN_3_perm, IC_LN_4_perm, IC_LN_5_perm, IC_ST_0_perm; int IC_ST_1_perm, IC_ST_2_perm, IC_ST_3_perm, IC_ST_4_perm; int IO_LN_0_perm, IO_LN_1_perm, IO_LN_2_perm, KH_LN_0_perm; int KH_LN_1_perm, KH_LN_2_perm, KH_LN_3_perm, KH_LN_4_perm; int KH_LN_5_perm, KH_LN_6_perm, KH_LN_7_perm, KH_LN_8_perm; int KH_ST_0_perm, KH_ST_1_perm, KH_ST_2_perm, KH_ST_3_perm; int KH_ST_4_perm, KH_ST_5_perm, KH_ST_6_perm, KIO_LN_0_perm; int KIO_LN_1_perm, OC_JCT_0_perm, OC_LN_0_perm, OC_LN_1_perm; int OC_LN_2_perm, OC_LN_3_perm, OC_LN_4_perm, OC_LN_5_perm; int OC_ST_0_perm, OC_ST_1_perm, OC_ST_2_perm, OC_ST_3_perm; int OC_ST_4_perm, OI_LN_0_perm, OI_LN_1_perm, OI_LN_2_perm; bool perm_in_R, perm_out_R, perm_in_L, perm_out_L; // Debug flag for additional output bool debug = false; // Cleanup flag for halting the trains at home station tracks bool cleanup = false; // Variable, that gives the number of trains to C-Controller for stability check int trainCount; // Set of constants for binding to referenced SCCharts const int c_EINS = 1; const int c_ZWEI = 2; const int c_DREI = 3; const int c_VIER = 4; const int c_FUENF = 5; // State initializing the trains on corresponding tracks initial state init references initRailway11Trains --> run; // State handling the train schedules state run { // Regions handling the mutual exclusion on the track segments region Mutexes: // State referenced to the MutexController for 11 Trains initial state Mutexes references mutexRailway11Trains; region KH_Mutexes: // State referenced to additional MutexController for KH initial state KH_Mutexes references kh_mutex; // Regions that contain the schedules for individual trains //-------------------------------------------------------------------------------------- // Region with schedule for train 4 region Train4 : // State with the schedule for train 4 initial state train4 { // Annotation for replacing following constant in the hostcode of referenced SCChart @alterHostcode // Number of the train for identifying on track segments const int trainNum = 4; // Variable specifying the track, where the train arrives at, // and for transmitting the track number to next Station-2-Station controller int arrivalTrack = 3; // Schedule of train 4: train drives only in the IC, should use station track 3 // State Round referenced to ICIC Station-2-Station controller initial state Round references ICIC bind depTrack to arrivalTrack, destTrack to c_DREI, arrTrack to arrivalTrack // Transition to checking state >-> Choice; // State for checking, when the train should halt and if the train is on corresponding track state Choice // Transition for driving additional circle, if cleanup = false or wrong track used --> Round with !cleanup | !(arrivalTrack == 3) // Transition to final state --> Done; final state Done; }; // Region with schedule for train 5, identical to region above region Train5 : initial state train5 { @alterHostcode const int trainNum = 5; int arrivalTrack = 2; initial state Round references ICIC bind depTrack to arrivalTrack, destTrack to c_ZWEI, arrTrack to arrivalTrack >-> Choice; state Choice --> Round with !cleanup | !(arrivalTrack == 2) --> Done; final state Done; }; // Region with schedule for train 9, identical to region above region Train9 : initial state train9 { @alterHostcode const int trainNum = 9; int arrivalTrack = 1; initial state Round references ICIC bind depTrack to arrivalTrack, destTrack to c_EINS, arrTrack to arrivalTrack >-> Choice; state Choice --> Round with !cleanup | !(arrivalTrack == 1) --> Done; final state Done; }; // Region with schedule for train 7 region Train7 : initial state train7 { @alterHostcode const int trainNum = 7; int arrivalTrack = 1; // Schedule of train 7: train drives from OC-Station track 1 to IC-Station track 2 and back // arrivalTrack used for transmitting the number of station track where train arrived on // to next controller where the train starts on initial state OCtoIC references OCIC bind depTrack to arrivalTrack, destTrack to c_ZWEI, arrTrack to arrivalTrack // Transition to next Station-2-Station controller >-> ICtoOC; state ICtoOC references ICOC bind depTrack to arrivalTrack, destTrack to c_EINS, arrTrack to arrivalTrack // Transition to checking state because train at home station >-> Choice; // State for checking, when the train should halt and if the train is on corresponding track state Choice // Transition for driving additional circle, if cleanup = false or wrong track used --> OCtoIC with !cleanup | !(arrivalTrack == 1) // Transition to final state --> Done; final state Done; }; }; } |
...
Code Block | ||||
---|---|---|---|---|
| ||||
//
// Structure of a Station-2-Station controller from Station * to Station *
//
scchart STST " * to * Controller " {
// Set of permission variables for required tracks
input int *_perm;
// Set of request variables for required tracks for 11 trains
output bool *_req[11];
// Train number
input int trainNum;
// Number of the departure track in a station
input int depTrack;
// Number of the destination track in a station
input int destTrack;
// Cleanup flag for selecting the destination track
input bool cleanup;
// Debug flag for additional output
input bool debug;
// Arrival track
output int arrTrack;
// Variable with value for arrTrack for selecting correct station elements
int i_arrOnTrack;
// Handles departing from a station *
initial state *_ST {
// hostcode call for additional output when debug
entry debug / 'println([trainNum][ST-ST] ... )';
// State, which sets requests for needed tracks
initial state waitForPerm {
entry / *_ST_4_req[trainNum] = true;
entry / *_LN_0_req[trainNum] = true;
}
// Transition is taken, if all permissions are received
--> gotPerm with (*_ST_4_perm == trainNum) & (*_LN_0_perm == trainNum)
// Transition is taken, if some (not all) permissions are received
--> backOff with (*_ST_4_perm == trainNum) | (*_LN_0_perm == trainNum);
// State for waiting an additional tick when not all permissions are received
state backOff
--> backOff1;
// State, which releases the requests for needed tracks
state backOff1 {
entry / *_ST_4_req[trainNum] = false;
entry / *_LN_0_req[trainNum] = false;
}
// Transition to repeat requesting permissions procedure
--> waitForPerm;
final state gotPerm;
}
// Transition to the departure state
>-> Dep_*_ST;
// State, which handles the departure of a train
state Dep_*_ST {
// Set of entry-Actions with hostcode calls to set tracks, points and signals according to depTrack
entry / 'railPoint(*,STRAIGHT)';
entry / 'railSignal(*_LN_0, FWD, RED)';
entry / 'railTrack(*_LN_0,FWD,trainNum,NORMAL)';
entry / 'railTrack(*_ST_4,FWD,trainNum,NORMAL)';
entry depTrack == 1 / 'railSignal(*_ST_1, FWD, GREEN)';
entry depTrack == 2 / 'railSignal(*_ST_2, FWD, GREEN)';
entry depTrack == 3 / 'railSignal(*_ST_3, FWD, GREEN)';
//...
// Transition to next track segment, if contact is triggered
} --> *_LN_0 with 'railContact(*_LN_0,0)';
// ----------------------------------------------------------------------------------------------------------------
// Set of track segment controlling states such as follows
// ----------------------------------------------------------------------------------------------------------------
// Transition to next track segment, if contact is triggered
state *_LN_0 {
// Hostcode calls for outputs
entry / 'println("[trainNum][ST-ST] Entering *_LN_0")';
entry debug / 'println("[trainNum][ST-ST] Requesting permission for *_LN_1")';
// Entry-Actions with hostcode calls to set previous signal according to depTrack to RED
entry depTrack == 1 / 'railSignal(*_ST_1, FWD, RED)';
entry depTrack == 2 / 'railSignal(*_ST_2, FWD, RED)';
entry depTrack == 3 / 'railSignal(*_ST_3, FWD, RED)';
// Requesting the next track segment
entry / *_LN_1_req[trainNum] = true;
// Region for handling train driving
region Travel:
initial state Entry
// Transition to continuing state, if permitted
--> Continue with 'railContact(*_LN_0,0)' & (*_LN_1_perm == trainNum)
// Transition to slowing down else
--> Slowdown with 'railContact(*_LN_0,0)';
// State for slowing down the train
state Slowdown {
entry debug / 'println("[trainNum][ST-ST] Slowing down on *_LN_0")';
// Entry-Action with hostcode calls for slowing down the train
entry / 'railTrack(*_LN_0,FWD,trainNum,CAUTION)';
}
// Transition to waiting state
--> Waiting with 'railContact(*_LN_0,1)'
// Transition to continuing state, if permitted
--> Continue with *_LN_1_perm == trainNum;
// State for train waiting on permission
state Waiting {
entry debug / 'println("[trainNum][ST-ST] Stopping on *_LN_0")';
// Entry-Action with hostcode call for stopping the train
entry / 'railTrackBrake(*_LN_0)';
}
--> Continue with *_LN_1_perm == trainNum;
// State to continuing driving on the track
final state Continue {
entry debug / 'println("[trainNum][ST-ST] Continuing on *_LN_0")';
// Entry-Actions with hostcode calls to set tracks and signals for driving
entry / 'railSignal(*_LN_0,FWD,GREEN)';
entry / 'railTrack(*_LN_0,FWD,trainNum,NORMAL)';
entry / 'railTrack(*_LN_1,FWD,trainNum,NORMAL)';
entry / 'railSignal(*_LN_1, FWD, RED)';
};
// Region for handling cleanup functionalities
region Cleanup:
initial state Entry
// Transition to cleanup state
--> cleanup with 'railContact(*_LN_0,0)';
// State for cleaning up the previous track segments
final state cleanup {
entry debug / 'println("[trainNum][ST-ST] Entered *_LN_0 completely")';
// Entry-Action with hostcode call to switching off the previous track
entry / 'railTrackOff(*_ST_4)';
// Entry-Action to release the previous track
entry / *_ST_4_req[trainNum] = false;
};
// Transition to transitional state
}>-> *_LN_0_*_LN_1;
state *_LN_0_*_LN_1
// Transition to next track segment, if contact is triggered
--> *_LN_1 with 'railContact(*_LN_1,0)';
// ----------------------------------------------------------------------------------------------------------------
// State for entering a station
state *_LN_5 {
// Variable for checking all needed permissions
int perm_all_next_segments = false;
entry / 'println("[trainNum][ST-ST] Entering *_LN_5")';
entry / 'railSignal(*_LN_4, FWD, RED)';
// Region for handling train driving such as above,
// only with perm_all_next_segments for permitting more than one track
region Travel:
initial state Entry
--> Continue with 'railContact(*_LN_5,0)' & perm_all_next_segments
--> Slowdown with 'railContact(*_LN_5,0)';
state Slowdown {
entry debug / 'println("[trainNum][ST-ST] Slowing down on *_LN_5")';
entry / 'railTrack(*_LN_5,FWD,trainNum,CAUTION)';
}
--> Waiting with 'railContact(*_LN_5,1)'
--> Continue with perm_all_next_segments;
state Waiting {
entry debug / 'println("[trainNum][ST-ST] Stopping on *_LN_5")';
entry / 'railTrackBrake(*_LN_5)';
}
--> Continue with perm_all_next_segments;
final state Continue {
entry debug / 'println("[trainNum][ST-ST] Continuing on *_LN_5")';
entry i_arrOnTrack == 1 / 'railTrack(*_ST_1,FWD,trainNum,NORMAL)';
entry i_arrOnTrack == 2 / 'railTrack(*_ST_2,FWD,trainNum,NORMAL)';
entry i_arrOnTrack == 3 / 'railTrack(*_ST_3,FWD,trainNum,NORMAL)';
//...
entry / arrTrack = i_arrOnTrack;
};
// Region for handling cleanup-functionalities such as above
region Cleanup:
initial state Entry
--> cleanup with 'railContact(*_LN_5,0)';
final state cleanup {
entry debug / 'println("[trainNum][ST-ST] Entered *_LN_5 completely")';
entry / 'railTrackOff(*_LN_4)';
entry / *_LN_4_req[trainNum] = false;
};
// Region for handling permissions of all needed tracks
region Permissions:
// State for requesting all needed tracks according to destination track and cleanup-Flag
initial state checking {
entry / *_ST_0_req[trainNum] = true;
entry destTrack == 1 | !cleanup / *_ST_1_req[trainNum] = true;
entry destTrack == 2 | !cleanup / *_ST_2_req[trainNum] = true;
entry destTrack == 3 | !cleanup / *_ST_3_req[trainNum] = true;
}
// Transitions for permitted tracks match wished tracks
--> success with destTrack == 1 & *_ST_0_perm == trainNum & *_ST_1_perm == trainNum / i_arrOnTrack = 1
--> success with destTrack == 2 & *_ST_0_perm == trainNum & *_ST_2_perm == trainNum / i_arrOnTrack = 2
--> success with destTrack == 3 & *_ST_0_perm == trainNum & *_ST_3_perm == trainNum / i_arrOnTrack = 3
// Transitions for permitted tracks don't match wished tracks
--> success with *_ST_0_perm == trainNum & *_ST_1_perm == trainNum / i_arrOnTrack = 1
--> success with *_ST_0_perm == trainNum & *_ST_2_perm == trainNum / i_arrOnTrack = 2
--> success with *_ST_0_perm == trainNum & *_ST_3_perm == trainNum / i_arrOnTrack = 3
// Transition for not all tracks permitted
--> resolving with *_ST_0_perm == trainNum | *_ST_3_perm == trainNum | *_ST_2_perm == trainNum | *_ST_1_perm == trainNum;
// State for waiting an additional tick
state resolving
--> resolving1;
// State for releasing track requests
state resolving1 {
entry / *_ST_0_req[trainNum] = false;
entry / *_ST_1_req[trainNum] = false;
entry / *_ST_2_req[trainNum] = false;
entry / *_ST_3_req[trainNum] = false;
}
// Transition for trying the requesting again
--> checking;
// State for waiting an additional tick
state success
--> success1;
// State for releasing not used track requests
final state success1 {
entry !(i_arrOnTrack == 1) / *_ST_1_req[trainNum] = false;
entry !(i_arrOnTrack == 2) / *_ST_2_req[trainNum] = false;
entry !(i_arrOnTrack == 3) / *_ST_3_req[trainNum] = false;
// Settting perm_all_next_segments to true
entry / perm_all_next_segments = true;
};
// Transition to station entry states
}>-> *_LN_5_*_ST;
// State waiting for station entry
state *_LN_5_*_ST
--> Arr_*_ST with i_arrOnTrack == 1 & 'railContact(*_ST_1,0)'
--> Arr_*_ST with i_arrOnTrack == 2 & 'railContact(*_ST_2,0)'
--> Arr_*_ST with i_arrOnTrack == 3 & 'railContact(*_ST_3,0)';
// State for setting tracks, points and signals according to i_arrOnTrack
// and releasing previous track request
state Arr_*_ST {
entry / 'railSignal(*_LN_5, FWD, RED)';
entry / 'railTrackOff(*_LN_5)';
entry / 'railTrack(*_ST_0,FWD,trainNum,SLOW)';
entry i_arrOnTrack == 1 / 'railTrack(*_ST_1,FWD,trainNum,SLOW)';
entry i_arrOnTrack == 2 / 'railTrack(*_ST_2,FWD,trainNum,SLOW)';
entry i_arrOnTrack == 3 / 'railTrack(*_ST_3,FWD,trainNum,SLOW)';
entry / *_LN_5_req[trainNum] = false;
initial state SlowEntry
--> Slow with i_arrOnTrack == 1 & 'railContact(*_ST_1,0)'
--> Slow with i_arrOnTrack == 2 & 'railContact(*_ST_2,0)'
--> Slow with i_arrOnTrack == 3 & 'railContact(*_ST_3,0)';
// State for switching off previous track and releasing the request
state Slow {
entry / 'railTrackOff(*_ST_0)';
entry / *_ST_0_req[trainNum] = false;
}
// Transitions to halt state, when train is at second contact of a track segment
--> Halt with i_arrOnTrack == 1 & 'railContact(*_ST_1,1)'
--> Halt with i_arrOnTrack == 2 & 'railContact(*_ST_2,1)'
--> Halt with i_arrOnTrack == 3 & 'railContact(*_ST_3,1)';
final state Halt {
// Entry-Actions for braking the train on correct track
entry i_arrOnTrack == 1 / 'railTrackBrake(*_ST_1)';
entry i_arrOnTrack == 2 / 'railTrackBrake(*_ST_2)';
entry i_arrOnTrack == 3 / 'railTrackBrake(*_ST_3)';
// Entry-Actions for waiting for timer on correct track
entry i_arrOnTrack == 1 / 'railArrival(trainNum, *_ST_1)';
entry i_arrOnTrack == 2 / 'railArrival(trainNum, *_ST_2)';
entry i_arrOnTrack == 3 / 'railArrival(trainNum, *_ST_3)';
};
}
>-> done;
state done
// Transition to final state, if timer is ready
--> reallyDone with 'railDeparture(trainNum)';
final state reallyDone;
} |
Dynamic Controller
The dynamic controller handles all 11 Trains. For each train the controller has a region with a referenced dynamic scheduling. Thereby each train can follow an arbitrary schedule. Additionally the controller has a region for stable cleanup function.
Code Block | ||||
---|---|---|---|---|
| ||||
//
// Dynamic controller for 11 trains
//
scchart DynamicController11 {
// Set of request variables for all tracks for 11 trains
bool IC_JCT_0_req[11], IC_LN_0_req[11], IC_LN_1_req[11], IC_LN_2_req[11];
bool IC_LN_3_req[11], IC_LN_4_req[11], IC_LN_5_req[11], IC_ST_0_req[11];
bool IC_ST_1_req[11], IC_ST_2_req[11], IC_ST_3_req[11], IC_ST_4_req[11];
bool IO_LN_0_req[11], IO_LN_1_req[11], IO_LN_2_req[11], KH_LN_0_req[11];
bool KH_LN_1_req[11], KH_LN_2_req[11], KH_LN_3_req[11], KH_LN_4_req[11];
bool KH_LN_5_req[11], KH_LN_6_req[11], KH_LN_7_req[11], KH_LN_8_req[11];
bool KH_ST_0_req[11], KH_ST_1_req[11], KH_ST_2_req[11], KH_ST_3_req[11];
bool KH_ST_4_req[11], KH_ST_5_req[11], KH_ST_6_req[11], KIO_LN_0_req[11];
bool KIO_LN_1_req[11], OC_JCT_0_req[11], OC_LN_0_req[11], OC_LN_1_req[11];
bool OC_LN_2_req[11], OC_LN_3_req[11], OC_LN_4_req[11], OC_LN_5_req[11];
bool OC_ST_0_req[11], OC_ST_1_req[11], OC_ST_2_req[11], OC_ST_3_req[11];
bool OC_ST_4_req[11], OI_LN_0_req[11], OI_LN_1_req[11], OI_LN_2_req[11];
bool req_in_R , req_out_R , req_in_L , req_out_L;
// Set of permission variables for all tracks
int IC_JCT_0_perm, IC_LN_0_perm, IC_LN_1_perm, IC_LN_2_perm;
int IC_LN_3_perm, IC_LN_4_perm, IC_LN_5_perm, IC_ST_0_perm;
int IC_ST_1_perm, IC_ST_2_perm, IC_ST_3_perm, IC_ST_4_perm;
int IO_LN_0_perm, IO_LN_1_perm, IO_LN_2_perm, KH_LN_0_perm;
int KH_LN_1_perm, KH_LN_2_perm, KH_LN_3_perm, KH_LN_4_perm;
int KH_LN_5_perm, KH_LN_6_perm, KH_LN_7_perm, KH_LN_8_perm;
int KH_ST_0_perm, KH_ST_1_perm, KH_ST_2_perm, KH_ST_3_perm;
int KH_ST_4_perm, KH_ST_5_perm, KH_ST_6_perm, KIO_LN_0_perm;
int KIO_LN_1_perm, OC_JCT_0_perm, OC_LN_0_perm, OC_LN_1_perm;
int OC_LN_2_perm, OC_LN_3_perm, OC_LN_4_perm, OC_LN_5_perm;
int OC_ST_0_perm, OC_ST_1_perm, OC_ST_2_perm, OC_ST_3_perm;
int OC_ST_4_perm, OI_LN_0_perm, OI_LN_1_perm, OI_LN_2_perm;
bool perm_in_R , perm_out_R , perm_in_L , perm_out_L;
// Flags needed for stable cleanup function
//----------------------------------------------------------------------------------------
// Flags for trains are ready and back at home
bool trainDone[11];
// Flags for trains are on their home circle
bool circle[11];
// Flag for trains 0 to 7 are back at home and trains 8 to 10 are on their home circle
bool mainDone;
// Flag for all trains are back at home
bool allDone;
//----------------------------------------------------------------------------------------
// Debug flag for additional output
bool debug;
// Cleanup flag for halting the trains at home station tracks
bool cleanup;
// Variable, that gives the number of trains to C-Controller for stability check
int trainCount;
// Constant needed for binding to referenced SCCharts
const bool c_TRUE = true;
// State initializing the trains on corresponding tracks
initial state init references initRailway11Trains
>-> run;
// State handling the train schedules
state run {
// Region handling the cleanup function
region Abort:
initial state notDone
// Transition when trains 0 to 7 are back at home and trains 8 to 10 are on their home circle
--> mainDone with trainDone[0] & trainDone[1] & trainDone[2]
& trainDone[3] & trainDone[4] & trainDone[5]
& trainDone[6] & trainDone[7]
& circle[8] & circle[9] & circle[10];
// State for allowing trains 8 to 10 to halt on the home track
state mainDone
--> quitCircle with / mainDone = true;
// State waiting for trains 8 to 10 halt and setting flag for terminate the controller
state quitCircle
--> done with trainDone[8] & trainDone[9] & trainDone[10] / allDone = true;
final state done;
// Regions handling the mutual exclusion on the track segments
region Mutexes:
initial state Mutexes references mutexRailway11Trains
// terminates with a strong abort when all trains are at home
o-> done with allDone;
final state done;
region KH_Mutexes:
initial state KH_Mutexes references kh_mutex
// terminates with a strong abort when all trains are at home
o-> done with allDone;
final state done;
// Regions that contain the dynamic schedules for trains 0 to 7
//--------------------------------------------------------------------------------------
// Region with the dynamic schedule for train 0
region Train0:
initial state Train0 {
@alterHostcode
const int trainNum = 0
// Variable for saving the home track
int homeTrack = 1;
// Variable for saving the home station
int homeStation = 1;
// State referenced to dynamic scheduling
initial state drive
references DynamicSheduling
// Binding circleDone to true for halting at home if cleanup is set
bind circleDone to c_TRUE
// Set a flag and a light for train at home
>-> done with / 'railLight(10,1)'; trainDone[0] = true;
final state done;
}
>-> done;
final state done;
// ... (other regions for trains 1 to 7 such as before)
//--------------------------------------------------------------------------------------
// Regions that contain the dynamic schedules for trains 8 to 10
// Differences to regions above is that the trains 8 to 10 circle at home station circle
// until trains 0 to 7 are back at home station and track
// For this circleDone binds mainDone flag
//--------------------------------------------------------------------------------------
// Region with the dynamic schedule for train 8
region Train8:
initial state Train8 {
@alterHostcode
const int trainNum = 8
// Variable for saving the home track
int homeTrack = 5;
// Variable for saving the home station
int homeStation = 1;
// State referenced to dynamic scheduling
initial state drive
references DynamicSheduling
// Binding circleDone to mainDone for halting at home only if cleanup is set
// and trains 0 to 7 are at home and 8 to 10 on home circle
bind circleDone to mainDone
// Set a flag and a light for train at home
>-> done with / 'railLight(6,1)'; trainDone[8] = true;
final state done;
}
>-> done;
final state done;
// ... (other regions for trains 9 and 10 such as before)
//--------------------------------------------------------------------------------------
}
>-> flash;
// State for flashing the lights at the end of the controller
state flash
--> done with / 'railFlashLight()';
final state done;
} |