T3A1: Round and Round!

SCCharts Header
#include <stdio.h>
#include
"railway.h"
#include
"kicking.h"
#define NL "\n"
extern int second;
extern int contact[48][2];
extern struct railway_system *railway;
int tick();
int reset();
Main.c
#include <time.h>
#include
"ControllerTick.h"
struct railway_system *railway;
int contact[48][2];
int main(int argc, char *argv[])
{
   //initialize the railway system (and simulation)
   railway = railway_initsystem(&kicking);
    railway_openlinks_udp(railway,"node%02i","/dev/ttyS0");
    railway_startcontrol(railway,0,0);
   
    reset();
   time_t t_new;
   time_t t_old;
    time(&t_old);
    time(&t_new);
   
   while(railway_alive(railway)) {
        t_old = t_new;
        time(&t_new);
    
       if (t_new > t_old) {
          second = 1;
        } else {
          second = 0;
        }
       //read contacts
       int i;
       for (i = 0; i < 48; i++) {
           if (i != IC_JCT_0 &&
                i != IC_ST_0 &&
                i != IC_ST_4 &&
                i != KH_ST_0 &&
                i != KH_ST_6 &&
                i != OC_JCT_0 &&
                i != OC_ST_0 &&
                i != OC_ST_4) { //skip tracks with no contacts
                   contact[i][0] = getcontact(railway, i, 0, 0);
                    contact[i][1] = getcontact(railway, i, 1, 0);
            }
        }
        tick();
        second = 0;
        usleep(100);
    }
   // shut the system down
   railway_stopcontrol(railway, 1);
    railway_closelinks(railway);
    railway_donesystem(railway);
   return 0;
}
T3A1 SCChart
scchart Task2Controller {
 input bool second;
 initial state leave_IC_ST_2_TO_IC_LN_0 {
   entry / 'printf("leave_IC_ST_2_TO_IC_LN_0%s",NL)';
   entry / 'setsignal(railway, IC_ST_2, 1, GREEN)';
   entry / 'setpoint(railway, 23, BRANCH)';
   entry / 'setpoint(railway, 24, BRANCH)';
   entry / 'setpoint(railway, 29, STRAIGHT)';
   entry / 'settrack(railway, IC_ST_2, FWD, 100)';
   entry / 'settrack(railway, IC_ST_4, FWD, 100)';
   entry / 'settrack(railway, IC_LN_0, FWD, 100)';
   exit / 'settrack(railway, IC_ST_2, OFF, 0)';
   exit / 'setsignal(railway, IC_ST_2, 1, RED)';
  }
 --> enter_IC_LN_0 with 'contact[IC_LN_0][0]';
 state enter_IC_LN_0 {
   entry / 'printf("enter_IC_LN_0%s",NL)';
  }
 --> travel_IC_LN_0 with 'contact[IC_LN_0][0]';
 state travel_IC_LN_0 {
   entry / 'printf("travel_IC_LN_0%s",NL)';
   entry / 'settrack(railway, IC_ST_4, OFF, 0)';
  }
 --> leave_IC_LN_0 with 'contact[IC_LN_0][1]';
 state leave_IC_LN_0 {
   entry / 'printf("leave_IC_LN_0%s",NL)';
   entry / 'setsignal(railway, IC_LN_0, 1, GREEN)';
   entry / 'settrack(railway, IC_LN_0, FWD, 100)';
   entry / 'settrack(railway, IC_LN_1, FWD, 100)';
   exit / 'setsignal(railway, IC_LN_0, 1, RED)';
  }
 --> enter_IC_LN_1 with 'contact[IC_LN_1][0]';
 state enter_IC_LN_1 {
   entry / 'printf("enter_IC_LN_1%s",NL)';
  }
 --> travel_IC_LN_1 with 'contact[IC_LN_1][0]';
 state travel_IC_LN_1 {
   entry / 'printf("travel_IC_LN_1%s",NL)';
   entry / 'settrack(railway, IC_LN_0, OFF, 0)';
  }
 --> leave_IC_LN_1 with 'contact[IC_LN_1][1]';
 state leave_IC_LN_1 {
   entry / 'printf("leave_IC_LN_1%s",NL)';
   entry / 'setsignal(railway, IC_LN_1, 1, GREEN)';
   entry / 'settrack(railway, IC_LN_1, FWD, 100)';
   entry / 'settrack(railway, IC_LN_2, FWD, 100)';
   exit / 'setsignal(railway, IC_LN_1, 1, RED)';
  }
 --> enter_IC_LN_2 with 'contact[IC_LN_2][0]';
 state enter_IC_LN_2 {
   entry / 'printf("enter_IC_LN_2%s",NL)';
  }
 --> travel_IC_LN_2 with 'contact[IC_LN_2][0]';
 state travel_IC_LN_2 {
   entry / 'printf("travel_IC_LN_2%s",NL)';
   entry / 'settrack(railway, IC_LN_1, OFF, 0)';
  }
 --> leave_IC_LN_2 with 'contact[IC_LN_2][1]';
 state leave_IC_LN_2 {
   entry / 'printf("leave_IC_LN_2%s",NL)';
   entry / 'setsignal(railway, IC_LN_2, 1, GREEN)';
   entry / 'settrack(railway, IC_LN_2, FWD, 100)';
   entry / 'settrack(railway, IC_LN_3, FWD, 100)';
   exit / 'setsignal(railway, IC_LN_2, 1, RED)';
  }
 --> enter_IC_LN_3 with 'contact[IC_LN_3][0]';
 state enter_IC_LN_3 {
   entry / 'printf("enter_IC_LN_3%s",NL)';
  }
 --> travel_IC_LN_3 with 'contact[IC_LN_3][0]';
 state travel_IC_LN_3 {
   entry / 'printf("travel_IC_LN_3%s",NL)';
   entry / 'settrack(railway, IC_LN_2, OFF, 0)';
  }
 --> leave_IC_LN_3 with 'contact[IC_LN_3][1]';
 state leave_IC_LN_3 {
   entry / 'printf("leave_IC_LN_3%s",NL)';
   entry / 'setsignal(railway, IC_LN_3, 1, GREEN)';
   entry / 'settrack(railway, IC_LN_3, FWD, 100)';
   entry / 'settrack(railway, IC_LN_4, FWD, 100)';
   exit / 'setsignal(railway, IC_LN_3, 1, RED)';
  }
 --> enter_IC_LN_4 with 'contact[IC_LN_4][0]';
 state enter_IC_LN_4 {
   entry / 'printf("enter_IC_LN_4%s",NL)';
  }
 --> travel_IC_LN_4 with 'contact[IC_LN_4][0]';
 state travel_IC_LN_4 {
   entry / 'printf("travel_IC_LN_4%s",NL)';
   entry / 'settrack(railway, IC_LN_3, OFF, 0)';
  }
 --> leave_IC_LN_4 with 'contact[IC_LN_4][1]';
 state leave_IC_LN_4 {
   entry / 'printf("leave_IC_LN_4%s",NL)';
   entry / 'setsignal(railway, IC_LN_4, 1, GREEN)';
   entry / 'settrack(railway, IC_LN_4, FWD, 100)';
   entry / 'setpoint(railway, 11, STRAIGHT)';
   entry / 'setpoint(railway, 13, STRAIGHT)';
   entry / 'settrack(railway, IC_JCT_0, FWD, 100)';
   entry / 'settrack(railway, IC_LN_5, FWD, 100)';
   exit / 'setsignal(railway, IC_LN_4, 1, RED)';
  }
 --> enter_IC_LN_5 with 'contact[IC_LN_5][0]';
 state enter_IC_LN_5 {
   entry / 'printf("enter_IC_LN_5%s",NL)';
  }
 --> travel_IC_LN_5 with 'contact[IC_LN_5][0]';
 state travel_IC_LN_5 {
   entry / 'printf("travel_IC_LN_5%s",NL)';
   entry / 'settrack(railway, IC_LN_4, OFF, 0)';
   entry / 'settrack(railway, IC_JCT_0, OFF, 0)';
  }
 --> leave_IC_LN_5_TO_IC_ST_2 with 'contact[IC_LN_5][1]';
 state leave_IC_LN_5_TO_IC_ST_2 {
   entry / 'printf("leave_IC_LN_5_TO_IC_ST_2%s",NL)';
   entry / 'setsignal(railway, IC_LN_5, 1, GREEN)';
   entry / 'settrack(railway, IC_LN_5, FWD, 100)';
   entry / 'setpoint(railway, 18, STRAIGHT)';
   entry / 'setpoint(railway, 20, BRANCH)';
   entry / 'setpoint(railway, 19, BRANCH)';
   entry / 'settrack(railway, IC_ST_0, FWD, 100)';
   entry / 'settrack(railway, IC_ST_2, FWD, 100)';
   exit / 'setsignal(railway, IC_LN_5, 1, RED)';
  }
 --> enter_IC_ST_2 with 'contact[IC_ST_2][0]';
 state enter_IC_ST_2 {
   entry / 'printf("enter_IC_ST_2%s",NL)';
   entry / 'settrack(railway, IC_LN_5, OFF, 0)';
   entry / 'settrack(railway, IC_ST_0, FWD, 40)';
   entry / 'settrack(railway, IC_ST_2, FWD, 40)';
  }
 --> travel_IC_ST_2 with 'contact[IC_ST_2][0]';
 state travel_IC_ST_2 {
   entry / 'printf("travel_IC_ST_2%s",NL)';
   entry / 'settrack(railway, IC_ST_0, OFF, 0)';
  }
 --> stop_and_wait_IC_ST_2 with 'contact[IC_ST_2][1]';
 state stop_and_wait_IC_ST_2 {
   entry / 'printf("stop_and_wait_IC_ST_2%s",NL)';
   entry / 'settrack(railway, IC_ST_2, BRAKE, 0)';
   initial state wait_0
   --> wait_1 with second;
   state wait_1
   --> wait_2 with second;
   state wait_2
   --> wait_3 with second;
   state wait_3
   --> wait_4 with second;
   state wait_4
   --> wait_5 with second;
state wait_5
   --> wait_6 with second;
state wait_6
   --> wait_7 with second;
state wait_7
   --> wait_8 with second;
state wait_8
   --> wait_9 with second;
   state wait_9
   --> wait_10 with second;
    final state wait_10;
  }
 >-> leave_IC_ST_2_TO_IC_LN_0;
}

Testet with simulation and real railway.

T3A2: To boldly model where no one has modeled before...

T3A2 SCChart
@VHLayout
scchart Task2Controller {
 input bool second;
 bool REQ_T1_IC_ST_0 = false;
 bool REQ_T1_IC_ST_4 = false;
 bool REQ_T1_IC_ST_2 = true;
 bool PEM_T1_IC_ST_0 = false;
 bool PEM_T1_IC_ST_4 = false;
 bool PEM_T1_IC_ST_2 = true;
 bool REQ_T2_IC_ST_0 = false;
 bool REQ_T2_IC_ST_4 = false;
 bool REQ_T2_IC_ST_2 = false;
 bool PEM_T2_IC_ST_0 = false;
 bool PEM_T2_IC_ST_4 = false;
 bool PEM_T2_IC_ST_2 = false;
 entry / 'setsignal(railway, -1, -1, RED)';
 region innerCircle_T1:
 initial state leave_IC_ST_2_TO_IC_LN_0 {
   entry / 'printf("leave_IC_ST_2_TO_IC_LN_0%s",NL)';
   entry / 'setsignal(railway, IC_ST_2, 1, GREEN)';
   entry / 'setpoint(railway, 23, BRANCH)';
   entry / 'setpoint(railway, 24, BRANCH)';
   entry / 'setpoint(railway, 29, STRAIGHT)';
   entry / 'settrack(railway, IC_ST_2, FWD, 100)';
   entry / 'settrack(railway, IC_ST_4, FWD, 100)';
   entry / 'settrack(railway, IC_LN_0, FWD, 100)';
   exit / 'settrack(railway, IC_ST_2, OFF, 0)';
   exit / REQ_T1_IC_ST_2 = false;
   exit / 'setsignal(railway, IC_ST_2, 1, RED)';
  }
 --> enter_IC_LN_0 with 'contact[IC_LN_0][0]';
 state enter_IC_LN_0 {
   entry / 'printf("enter_IC_LN_0%s",NL)';
  }
 --> travel_IC_LN_0 with 'contact[IC_LN_0][0]';
 state travel_IC_LN_0 {
   entry / 'printf("travel_IC_LN_0%s",NL)';
   entry / 'settrack(railway, IC_ST_4, OFF, 0)';
   entry / REQ_T1_IC_ST_4 = false;
  }
 --> leave_IC_LN_0 with 'contact[IC_LN_0][1]';
 state leave_IC_LN_0 {
   entry / 'printf("leave_IC_LN_0%s",NL)';
   entry / 'setsignal(railway, IC_LN_0, 1, GREEN)';
   entry / 'settrack(railway, IC_LN_0, FWD, 100)';
   entry / 'settrack(railway, IC_LN_1, FWD, 100)';
   exit / 'setsignal(railway, IC_LN_0, 1, RED)';
  }
 --> enter_IC_LN_1 with 'contact[IC_LN_1][0]';
 state enter_IC_LN_1 {
   entry / 'printf("enter_IC_LN_1%s",NL)';
  }
 --> travel_IC_LN_1 with 'contact[IC_LN_1][0]';
 state travel_IC_LN_1 {
   entry / 'printf("travel_IC_LN_1%s",NL)';
   entry / 'settrack(railway, IC_LN_0, OFF, 0)';
  }
 --> leave_IC_LN_1 with 'contact[IC_LN_1][1]';
 state leave_IC_LN_1 {
   entry / 'printf("leave_IC_LN_1%s",NL)';
   entry / 'setsignal(railway, IC_LN_1, 1, GREEN)';
   entry / 'settrack(railway, IC_LN_1, FWD, 100)';
   entry / 'settrack(railway, IC_LN_2, FWD, 100)';
   exit / 'setsignal(railway, IC_LN_1, 1, RED)';
  }
 --> enter_IC_LN_2 with 'contact[IC_LN_2][0]';
 state enter_IC_LN_2 {
   entry / 'printf("enter_IC_LN_2%s",NL)';
  }
 --> travel_IC_LN_2 with 'contact[IC_LN_2][0]';
 state travel_IC_LN_2 {
   entry / 'printf("travel_IC_LN_2%s",NL)';
   entry / 'settrack(railway, IC_LN_1, OFF, 0)';
  }
 --> leave_IC_LN_2 with 'contact[IC_LN_2][1]';
 state leave_IC_LN_2 {
   entry / 'printf("leave_IC_LN_2%s",NL)';
   entry / 'setsignal(railway, IC_LN_2, 1, GREEN)';
   entry / 'settrack(railway, IC_LN_2, FWD, 100)';
   entry / 'settrack(railway, IC_LN_3, FWD, 100)';
   exit / 'setsignal(railway, IC_LN_2, 1, RED)';
  }
 --> enter_IC_LN_3 with 'contact[IC_LN_3][0]';
 state enter_IC_LN_3 {
   entry / 'printf("enter_IC_LN_3%s",NL)';
  }
 --> travel_IC_LN_3 with 'contact[IC_LN_3][0]';
 state travel_IC_LN_3 {
   entry / 'printf("travel_IC_LN_3%s",NL)';
   entry / 'settrack(railway, IC_LN_2, OFF, 0)';
  }
 --> leave_IC_LN_3 with 'contact[IC_LN_3][1]';
 state leave_IC_LN_3 {
   entry / 'printf("leave_IC_LN_3%s",NL)';
   entry / 'setsignal(railway, IC_LN_3, 1, GREEN)';
   entry / 'settrack(railway, IC_LN_3, FWD, 100)';
   entry / 'settrack(railway, IC_LN_4, FWD, 100)';
   exit / 'setsignal(railway, IC_LN_3, 1, RED)';
  }
 --> enter_IC_LN_4 with 'contact[IC_LN_4][0]';
 state enter_IC_LN_4 {
   entry / 'printf("enter_IC_LN_4%s",NL)';
  }
 --> travel_IC_LN_4 with 'contact[IC_LN_4][0]';
 state travel_IC_LN_4 {
   entry / 'printf("travel_IC_LN_4%s",NL)';
   entry / 'settrack(railway, IC_LN_3, OFF, 0)';
  }
 --> leave_IC_LN_4 with 'contact[IC_LN_4][1]';
 state leave_IC_LN_4 {
   entry / 'printf("leave_IC_LN_4%s",NL)';
   entry / 'setsignal(railway, IC_LN_4, 1, GREEN)';
   entry / 'settrack(railway, IC_LN_4, FWD, 100)';
   entry / 'setpoint(railway, 11, STRAIGHT)';
   entry / 'setpoint(railway, 13, STRAIGHT)';
   entry / 'settrack(railway, IC_JCT_0, FWD, 100)';
   entry / 'settrack(railway, IC_LN_5, FWD, 100)';
   exit / 'setsignal(railway, IC_LN_4, 1, RED)';
  }
 --> enter_IC_LN_5 with 'contact[IC_LN_5][0]';
 state enter_IC_LN_5 {
   entry / 'printf("enter_IC_LN_5%s",NL)';
  }
 --> travel_IC_LN_5 with 'contact[IC_LN_5][0]';
 state travel_IC_LN_5 {
   entry / 'printf("travel_IC_LN_5%s",NL)';
   entry / 'settrack(railway, IC_LN_4, OFF, 0)';
   entry / 'settrack(railway, IC_JCT_0, OFF, 0)';
  }
 --> try_leave_IC_LN_5_TO_IC_ST_2 with 'contact[IC_LN_5][1]';
 state try_leave_IC_LN_5_TO_IC_ST_2 {
   entry / REQ_T1_IC_ST_0 = true;
   entry / REQ_T1_IC_ST_2 = true;
   entry / 'printf("try_leave_IC_LN_5_TO_IC_ST_2%s",NL)';
  }
 --> leave_IC_LN_5_TO_IC_ST_2 immediate with PEM_T1_IC_ST_0 && PEM_T1_IC_ST_2
 --> wait_leave_IC_LN_5_TO_IC_ST_2 immediate;
 state wait_leave_IC_LN_5_TO_IC_ST_2 {
   entry / 'printf("wait_leave_IC_LN_5_TO_IC_ST_2%s",NL)';
   entry / 'settrack(railway, IC_LN_5, BRAKE, 0)';
  }
 --> leave_IC_LN_5_TO_IC_ST_2 with PEM_T1_IC_ST_0 && PEM_T1_IC_ST_2;
 state leave_IC_LN_5_TO_IC_ST_2 {
   entry / 'printf("leave_IC_LN_5_TO_IC_ST_2%s",NL)';
   entry / 'setsignal(railway, IC_LN_5, 1, GREEN)';
   entry / 'settrack(railway, IC_LN_5, FWD, 100)';
   entry / 'setpoint(railway, 18, STRAIGHT)';
   entry / 'setpoint(railway, 20, BRANCH)';
   entry / 'setpoint(railway, 19, BRANCH)';
   entry / 'settrack(railway, IC_ST_0, FWD, 100)';
   entry / 'settrack(railway, IC_ST_2, FWD, 100)';
   exit / 'setsignal(railway, IC_LN_5, 1, RED)';
  }
 --> enter_IC_ST_2 with 'contact[IC_ST_2][0]';
 state enter_IC_ST_2 {
   entry / 'printf("enter_IC_ST_2%s",NL)';
   entry / 'settrack(railway, IC_LN_5, OFF, 0)';
   entry / 'settrack(railway, IC_ST_0, FWD, 40)';
   entry / 'settrack(railway, IC_ST_2, FWD, 40)';
  }
 --> travel_IC_ST_2 with 'contact[IC_ST_2][0]';
 state travel_IC_ST_2 {
   entry / 'printf("travel_IC_ST_2%s",NL)';
   entry / 'settrack(railway, IC_ST_0, OFF, 0)';
   entry / REQ_T1_IC_ST_0 = false;
  }
 --> stop_and_wait_IC_ST_2 with 'contact[IC_ST_2][1]';
 state stop_and_wait_IC_ST_2 {
   entry / 'printf("stop_and_wait_IC_ST_2%s",NL)';
   entry / 'settrack(railway, IC_ST_2, BRAKE, 0)';
   initial state wait_0
   --> wait_1 with second;
   state wait_1
   --> wait_2 with second;
   state wait_2
   --> wait_3 with second;
   state wait_3
   --> wait_4 with second;
   state wait_4
   --> wait_5 with second;
   final state wait_5;
  }
 >-> try_leave_IC_ST_2_TO_IC_LN_0;
 state try_leave_IC_ST_2_TO_IC_LN_0 {
   entry / REQ_T1_IC_ST_4 = true;
   entry / 'printf("try_leave_IC_ST_2_TO_IC_LN_0%s",NL)';
  }
 --> leave_IC_ST_2_TO_IC_LN_0 immediate with PEM_T1_IC_ST_4
 --> wait_leave_IC_ST_2_TO_IC_LN_0 immediate;
 state wait_leave_IC_ST_2_TO_IC_LN_0 {
   entry / 'printf("wait_leave_IC_ST_2_TO_IC_LN_0%s",NL)';
   entry / 'settrack(railway, IC_ST_2, BRAKE, 0)';
  }
 --> leave_IC_ST_2_TO_IC_LN_0 with PEM_T1_IC_ST_4;
 region kicking_T2: //--KICKING--
 initial state leave_KH_ST_3_TO_KIO_LN_0 {
   entry / 'printf("leave_KH_ST_3_TO_KIO_LN_0%s",NL)';
   entry / 'setsignal(railway, KH_ST_3, 0, GREEN)';
   entry / 'setpoint(railway, 0, BRANCH)';
   entry / 'setpoint(railway, 1, BRANCH)';
   entry / 'setpoint(railway, 2, BRANCH)';
   entry / 'setpoint(railway, 3, BRANCH)';
   entry / 'settrack(railway, KH_ST_3, REV, 100)';
   entry / 'settrack(railway, KH_ST_0, REV, 100)';
   entry / 'settrack(railway, KIO_LN_0, REV, 100)';
   exit / 'settrack(railway, KH_ST_3, OFF, 0)';
   exit / 'setsignal(railway, KH_ST_3, 0, RED)';
  }
 --> enter_KIO_LN_0 with 'contact[KIO_LN_0][1]';
 state enter_KIO_LN_0 {
   entry / 'printf("enter_KIO_LN_0%s",NL)';
  }
 --> travel_KIO_LN_0 with 'contact[KIO_LN_0][1]';
 state travel_KIO_LN_0 {
   entry / 'printf("travel_KIO_LN_0%s",NL)';
   entry / 'settrack(railway, KH_ST_0, OFF, 0)';
  }
 --> try_leave_KIO_LN_0_TO_IC_ST_2 with 'contact[KIO_LN_0][0]';
 state try_leave_KIO_LN_0_TO_IC_ST_2 {
   entry / 'printf("try_leave_KIO_LN_0_TO_IC_ST_2%s",NL)';
   entry / REQ_T2_IC_ST_0 = true;
   entry / REQ_T2_IC_ST_2 = true;
  }
 --> leave_KIO_LN_0_TO_IC_ST_2 immediate with PEM_T2_IC_ST_0 && PEM_T2_IC_ST_2
 --> wait_leave_KIO_LN_0_TO_IC_ST_2 immediate;
 state wait_leave_KIO_LN_0_TO_IC_ST_2 {
   entry / 'printf("wait_leave_KIO_LN_0_TO_IC_ST_2%s",NL)';
   entry / 'settrack(railway, KIO_LN_0, BRAKE, 0)';
  }
 --> leave_KIO_LN_0_TO_IC_ST_2 with PEM_T2_IC_ST_0 && PEM_T2_IC_ST_2;
 state leave_KIO_LN_0_TO_IC_ST_2 {
   entry / 'printf("leave_KIO_LN_0_TO_IC_ST_2%s",NL)';
   entry / 'setsignal(railway, KIO_LN_0, 0, GREEN)';
   entry / 'settrack(railway, KIO_LN_0, REV, 100)';
   entry / 'setpoint(railway, 16, BRANCH)';
   entry / 'setpoint(railway, 17, BRANCH)';
   entry / 'setpoint(railway, 18, BRANCH)';
   entry / 'setpoint(railway, 19, BRANCH)';
   entry / 'setpoint(railway, 20, BRANCH)';
   entry / 'settrack(railway, KIO_LN_0, REV, 100)';
   entry / 'settrack(railway, OC_ST_4, REV, 100)';
   entry / 'settrack(railway, IC_ST_0, FWD, 100)';
   entry / 'settrack(railway, IC_ST_2, FWD, 100)';
   exit / 'setsignal(railway, KIO_LN_0, 0, RED)';
  }
 --> enter_IC_ST_2 with 'contact[IC_ST_2][0]';
 state enter_IC_ST_2 {
   entry / 'printf("enter_IC_ST_2%s",NL)';
   entry / 'settrack(railway, KIO_LN_0, OFF, 0)';
   entry / 'settrack(railway, OC_ST_4, OFF, 0)';
   entry / 'settrack(railway, IC_ST_0, FWD, 40)';
   entry / 'settrack(railway, IC_ST_2, FWD, 40)';
  }
 --> travel_IC_ST_2 with 'contact[IC_ST_2][0]';
 state travel_IC_ST_2 {
   entry / 'printf("travel_IC_ST_2%s",NL)';
   entry / 'settrack(railway, IC_ST_0, OFF, 0)';
   entry / REQ_T2_IC_ST_0 = false;
  }
 --> stop_and_wait_IC_ST_2 with 'contact[IC_ST_2][1]';
 state stop_and_wait_IC_ST_2 {
   entry / 'printf("stop_and_wait_IC_ST_2%s",NL)';
   entry / 'settrack(railway, IC_ST_2, BRAKE, 0)';
   initial state wait_0
   --> wait_1 with second;
   state wait_1
   --> wait_2 with second;
   state wait_2
   --> wait_3 with second;
   state wait_3
   --> wait_4 with second;
   state wait_4
   --> wait_5 with second;
   final state wait_5;
  }
 >-> try_leave_IC_ST_2_TO_KIO_LN_1;
 state try_leave_IC_ST_2_TO_KIO_LN_1 {
   entry / REQ_T2_IC_ST_4 = true;
   entry / 'printf("try_leave_IC_ST_2_TO_KIO_LN_1%s",NL)';
  }
 --> leave_IC_ST_2_TO_KIO_LN_1 immediate with PEM_T2_IC_ST_4
 --> wait_leave_IC_ST_2_TO_KIO_LN_1 immediate;
 state wait_leave_IC_ST_2_TO_KIO_LN_1 {
   entry / 'printf("wait_leave_IC_ST_2_TO_KIO_LN_1%s",NL)';
   entry / 'settrack(railway, IC_ST_2, BRAKE, 0)';
  }
 --> leave_IC_ST_2_TO_KIO_LN_1 with PEM_T2_IC_ST_4;
 state leave_IC_ST_2_TO_KIO_LN_1 {
   entry / 'printf("leave_IC_ST_2_TO_KIO_LN_1%s",NL)';
   entry / 'setsignal(railway, IC_ST_2, 1, GREEN)';
   entry / 'setpoint(railway, 23, BRANCH)';
   entry / 'setpoint(railway, 24, BRANCH)';
   entry / 'setpoint(railway, 29, BRANCH)';
   entry / 'setpoint(railway, 27, STRAIGHT)';
   entry / 'setpoint(railway, 28, STRAIGHT)';
   entry / 'settrack(railway, IC_ST_2, FWD, 100)';
   entry / 'settrack(railway, IC_ST_4, FWD, 100)';
   entry / 'settrack(railway, OC_ST_0, REV, 100)';
   entry / 'settrack(railway, KIO_LN_1, REV, 100)';
   exit / 'settrack(railway, IC_ST_2, OFF, 0)';
   exit / REQ_T2_IC_ST_2 = false;
   exit / 'setsignal(railway, IC_ST_2, 1, RED)';
  }
 --> enter_KIO_LN_1 with 'contact[KIO_LN_1][1]';
 state enter_KIO_LN_1 {
   entry / 'printf("enter_KIO_LN_1%s",NL)';
  }
 --> travel_KIO_LN_1 with 'contact[KIO_LN_1][1]';
 state travel_KIO_LN_1 {
   entry / 'printf("travel_KIO_LN_1%s",NL)';
   entry / 'settrack(railway, IC_ST_4, OFF, 0)';
   entry / 'settrack(railway, OC_ST_0, OFF, 0)';
   entry / REQ_T2_IC_ST_4 = false;
  }
 --> leave_KIO_LN_1_TO_KH_ST_3 with 'contact[KIO_LN_1][0]';
 state leave_KIO_LN_1_TO_KH_ST_3 {
   entry / 'printf("leave_KIO_LN_1_TO_KH_ST_3%s",NL)';
   entry / 'setsignal(railway, KIO_LN_1, 0, GREEN)';
   entry / 'setpoint(railway, 9, BRANCH)';
   entry / 'setpoint(railway, 8, BRANCH)';
   entry / 'setpoint(railway, 7, BRANCH)';
   entry / 'setpoint(railway, 6, BRANCH)';
   entry / 'settrack(railway, KIO_LN_1, REV, 100)';
   entry / 'settrack(railway, KH_ST_6, REV, 100)';
   entry / 'settrack(railway, KH_ST_3, REV, 100)';
   exit / 'setsignal(railway, KIO_LN_1, 0, RED)';
  }
 --> enter_KH_ST_3 with 'contact[KH_ST_3][1]';
 state enter_KH_ST_3 {
   entry / 'printf("enter_KH_ST_3%s",NL)';
   entry / 'settrack(railway, KIO_LN_1, OFF, 0)';
   entry / 'settrack(railway, KH_ST_6, REV, 40)';
   entry / 'settrack(railway, KH_ST_3, REV, 40)';
  }
 --> travel_KH_ST_3 with 'contact[KH_ST_3][1]';
 state travel_KH_ST_3 {
   entry / 'printf("travel_KH_ST_3%s",NL)';
   entry / 'settrack(railway, KH_ST_6, OFF, 0)';
  }
 --> stop_and_wait_KH_ST_3 with 'contact[KH_ST_3][0]';
 state stop_and_wait_KH_ST_3 {
   entry / 'printf("stop_and_wait_KH_ST_3%s",NL)';
   entry / 'settrack(railway, KH_ST_3, BRAKE, 0)';
   initial state wait_0
   --> wait_1 with second;
   state wait_1
   --> wait_2 with second;
   state wait_2
   --> wait_3 with second;
   state wait_3
   --> wait_4 with second;
   state wait_4
   --> wait_5 with second;
   final state wait_5;
  }
 >-> leave_KH_ST_3_TO_KIO_LN_0;
 region Mutual_Exclusion_Handler:
 initial state lock_IC_ST_0
 //hold lock
 --> lock_IC_ST_2 immediate with REQ_T1_IC_ST_0 && PEM_T1_IC_ST_0 / PEM_T1_IC_ST_0 = true
 --> lock_IC_ST_2 immediate with REQ_T2_IC_ST_0 && PEM_T2_IC_ST_0 / PEM_T2_IC_ST_0 = true
 //switch lock  
 --> lock_IC_ST_2 immediate with !REQ_T1_IC_ST_0 && PEM_T1_IC_ST_0 && REQ_T2_IC_ST_0 / PEM_T1_IC_ST_0 = false; PEM_T2_IC_ST_0 = true
 --> lock_IC_ST_2 immediate with !REQ_T2_IC_ST_0 && PEM_T2_IC_ST_0 && REQ_T1_IC_ST_0 / PEM_T1_IC_ST_0 = true; PEM_T2_IC_ST_0 = false
 //take lock
 --> lock_IC_ST_2 immediate with REQ_T1_IC_ST_0 && !PEM_T1_IC_ST_0 / PEM_T1_IC_ST_0 = true
 --> lock_IC_ST_2 immediate with REQ_T2_IC_ST_0 && !PEM_T2_IC_ST_0 / PEM_T2_IC_ST_0 = true
 //release
 --> lock_IC_ST_2 immediate with !REQ_T1_IC_ST_0 && PEM_T1_IC_ST_0 / PEM_T1_IC_ST_0 = false
 --> lock_IC_ST_2 immediate with !REQ_T2_IC_ST_0 && PEM_T2_IC_ST_0 / PEM_T2_IC_ST_0 = false
 //change nothing
 --> lock_IC_ST_2 immediate;
 state lock_IC_ST_2
 //hold lock
 --> lock_IC_ST_4 immediate with REQ_T1_IC_ST_2 && PEM_T1_IC_ST_2 / PEM_T1_IC_ST_2 = true
 --> lock_IC_ST_4 immediate with REQ_T2_IC_ST_2 && PEM_T2_IC_ST_2 / PEM_T2_IC_ST_2 = true
 //switch lock  
 --> lock_IC_ST_4 immediate with !REQ_T1_IC_ST_2 && PEM_T1_IC_ST_2 && REQ_T2_IC_ST_2 / PEM_T1_IC_ST_2 = false; PEM_T2_IC_ST_2 = true
 --> lock_IC_ST_4 immediate with !REQ_T2_IC_ST_2 && PEM_T2_IC_ST_2 && REQ_T1_IC_ST_2 / PEM_T1_IC_ST_2 = true; PEM_T2_IC_ST_2 = false
 //take lock
 --> lock_IC_ST_4 immediate with REQ_T1_IC_ST_2 && !PEM_T1_IC_ST_2 / PEM_T1_IC_ST_2 = true
 --> lock_IC_ST_4 immediate with REQ_T2_IC_ST_2 && !PEM_T2_IC_ST_2 / PEM_T2_IC_ST_2 = true
 //release
 --> lock_IC_ST_4 immediate with !REQ_T1_IC_ST_2 && PEM_T1_IC_ST_2 / PEM_T1_IC_ST_2 = false
 --> lock_IC_ST_4 immediate with !REQ_T2_IC_ST_2 && PEM_T2_IC_ST_2 / PEM_T2_IC_ST_2 = false
 //change nothing
 --> lock_IC_ST_4 immediate;
 state lock_IC_ST_4
 //hold lock
 --> redo immediate with REQ_T1_IC_ST_4 && PEM_T1_IC_ST_4 / PEM_T1_IC_ST_4 = true
 --> redo immediate with REQ_T2_IC_ST_4 && PEM_T2_IC_ST_4 / PEM_T2_IC_ST_4 = true
 //switch lock  
 --> redo immediate with !REQ_T1_IC_ST_4 && PEM_T1_IC_ST_4 && REQ_T2_IC_ST_4 / PEM_T1_IC_ST_4 = false; PEM_T2_IC_ST_4 = true
 --> redo immediate with !REQ_T2_IC_ST_4 && PEM_T2_IC_ST_4 && REQ_T1_IC_ST_4 / PEM_T1_IC_ST_4 = true; PEM_T2_IC_ST_4 = false
 //take lock
 --> redo immediate with REQ_T1_IC_ST_4 && !PEM_T1_IC_ST_4 / PEM_T1_IC_ST_4 = true
 --> redo immediate with REQ_T2_IC_ST_4 && !PEM_T2_IC_ST_4 / PEM_T2_IC_ST_4 = true
 //release
 --> redo immediate with !REQ_T1_IC_ST_4 && PEM_T1_IC_ST_4 / PEM_T1_IC_ST_4 = false
 --> redo immediate with !REQ_T2_IC_ST_4 && PEM_T2_IC_ST_4 / PEM_T2_IC_ST_4 = false
 //change nothing
 --> redo immediate;
 state redo
 --> lock_IC_ST_0;
}

Untested due to tool restrictions.

T3A3: Important Thoughts

  1. Modules
    • Encapsulation of functionality
    • Separation of modules in single files
    • Re-usability
    • Customizability by module parameters
  2. Arrays
    • Arrays of SCCharts variables
    • correct dependency detection?
      • handling the complete array as one variable may cause numerous w-w-dependencies
      • requiring constant indices will undo advantages (variable index) of arrays
        hostcode indices may be hart to compute but would be nice. e.g. is_free[IC_LN_3]
  3. Scheduling constraints
    • Ability to exclude some variables from dependency calculations or setting constraints
    • Overcome conservative scheduler and allow semantically excluded parallel writes
    • Simplifies implementation of mutual exclusion
Tags: