chiark / gitweb /
giant reorg abolishes TrainNum most of the time; working on making it build
[trains.git] / hostside / safety.h
index 2cb34c3adaa1c1e2894fe595f3019cfed5943dc4..d7411315e8d4dc5920e4d3ecddbd6d2bfe95c4a0 100644 (file)
@@ -27,65 +27,73 @@ typedef short TimeInterval; /*ms*/
 /*========== state of the layout ==========*/
 
 typedef struct {
-  fixme init location;
-  fixme call init_fixed_train;
+  int step;
+  long speed;
+  TimeInterval upwait, downwait; /* between this insn and next one */
+} SpeedCurveEntry;
+
+struct Train {
+  /* Configuration (excluding speed curve): */
+  char *pname;
   int addr;
   Distance head, detectable, tail;
+
+  /* Location: */
   Segment *foredetect;     /* train's detectable part is at most maxinto   */
   Distance maxinto, uncertainty;   /*   into foredetect but train may be   */
   unsigned                         /*   uncertainty less far advanced      */
     backwards:1, /* train is moving backwards wrt its own front and back */
+
+  /* Speed: */
     estopping:1; /* set and cleared by speed.c */
   Speed speed; /* when accelerating/decelerating, is maximum at this moment */
-  
+
   struct {
-    const SpeedCurveEntry *curve;
-    int curvesz;
     int target; /* index into curve */
     int commanded; /* when ac-/decel, eq last value xmitted */
     TimeoutEvent more; 
     RetransmitUrgentNode rn;
+
+    /* Configuration for acceleration: */
+    SpeedCurveEntry *curve;
+    int curvesz;
   } accel;
-} TrainState;
+};
 
-typedef struct {
+struct Segment {
+  Train *owner;                                  /* or 0 */
   unsigned
-    owned:1, /* this track segment is reserved for a train */
     tr_backwards:1, /* train's motion is (would be) backwards wrt track */
     movfeat_moving:1, /* feature(s) have been told to change to movposcomb */
     cm_autostop:1, /* train should stop on detection */
     seg_inverted:1, /* polarity is inverted */
     tr_updated:1; /* for use by safety.c:lay_train etc.; otherwise 0 */
-  TimeInterval until_here, /* ) nonnegative; */  /* ) always valid but */
-    until_detect;          /* ) 0 if already */  /* )  only meaningful */
-  TrainNum owner;                                /* )  iff owned       */
+  TimeInterval until_here, /* ) nonnegative; */  /* ) always valid but      */
+    until_detect;          /* ) 0 if already */  /* )  meaningful iff owner */
   MovPosComb movposcomb;
-  /*polarity?*/
-} SegmentState;
-
-typedef struct {
-  TrainState trains[NUM_TRAINS];
-  SegmentState segments[NUM_SEGMENTS];
-} State;
+  const SegmentInfo *i;
+};
 
-extern State safety_state;
+extern int n_trains;
+extern Train *trains;
+extern Segment *segments;
 
 /*========== embed.c ==========*/
 /* surrounds the algorithms and machinery in a program: logging, error
  * handling, arg parsing, etc.
  */
 
-void vlogmsg(ErrorCode ec, TrainNum tran, SegmentNum segn,
+void vlogmsg(ErrorCode ec, Train *tra, const SegmentInfo *segi,
             const char *fmt, va_list al) __attribute__((format(printf,4,0)));
-void logmsg(ErrorCode ec, TrainNum tran, SegmentNum segn,
+void logmsg(ErrorCode ec, Train *tra, const SegmentInfo *segi,
            const char *fmt, ...) __attribute__((format(printf,4,5)));
 
-void safety_vpanic(TrainNum tran, SegmentNum segn, const char *fmt, va_list al)
+void safety_vpanic(Train *tra, Segment *seg, const char *fmt, va_list al)
      __attribute__((format(printf,3,0),noreturn));
-void safety_panic(TrainNum tran, SegmentNum segn, const char *fmt,...)
+void safety_panic(Train *tra, Segment *seg, const char *fmt,...)
      __attribute__((format(printf,3,4),noreturn));
 
-ErrorCode safety_problem(TrainNum tran, SegmentNum segn, const char *fmt, ...)
+ErrorCode safety_problem(Train *tra, Segment *seg, const char *fmt, ...)
      __attribute__((format(printf,3,4)));
      /* simple wrapper around vlogmsg; implies and returns EC_Safety */
 
@@ -96,28 +104,30 @@ ErrorCode safety_problem(TrainNum tran, SegmentNum segn, const char *fmt, ...)
  * etc.).
  */
 
-void safety_emergencystop(TrainNum);
+void safety_emergencystop(Train*);
   /* Callable directly in response to application command. */
 
-ErrorCode safety_requestspeed(TrainNum tran, long newspeed);
+ErrorCode safety_requestspeed(Train* tra, long newspeed);
   /* To be called only by the speed manager, thus indirectly from
    * user request.  Any error will have been logged.  On success,
    * ->speed has been updated.  Speed manager is responsible for
    * calling actual_setspeed.
    */
 
-void safety_setdirection(TrainNum tran, int sense_fixme_define_this_properly);
+void safety_setdirection(Train* tra, int sense_fixme_define_this_properly);
 
-void safety_notify_detection(SegmentNum segn);
+void safety_notify_detection(Segment *seg);
   /* Called by startup.c when new train detection occurs in state Run. */
 
 /*========== speedmgr.c ==========*/
 
-void speedmanager_speedchange_request(TrainNum tran, Speed speed);
-  /* Callable directly in response to application command. */
+void speedmanager_speedchange_request(Train *tra, long speed);
+  /* Callable directly in response to application command.
+   * speed may be LONG_MAX to mean maximum permitted.
+   */
 
-void speedmanager_emergencystop(TrainNum tran);
-void speedmanager_autostop(TrainNum tran);
+void speedmanager_emergencystop(Train *tra);
+void speedmanager_autostop(Train *tra);
   /* These are responsible for calling actual_setspeed.
    *
    * After speedmanager_autostop, ->speed will have been updated to a
@@ -125,6 +135,8 @@ void speedmanager_autostop(TrainNum tran);
    * been instructed to stop right now.
    */
 
+void speedmanager_reset_train(Train *tra);
+
 /*========== actual.c ==========*/
 /* actual.c should only be called from safety.c.
  * It is responsible for communicating with the PICs, including
@@ -135,11 +147,11 @@ void speedmanager_autostop(TrainNum tran);
  * will then call an actual_... function to notify the change.
  */
 
-void actual_setspeed(TrainNum tran);
-void actual_emergencystop(TrainNum tran);
+void actual_setspeed(Train *tra);
+void actual_emergencystop(Train *tra);
 
 void actual_inversions_start(void);
-void actual_inversions_segment(SegmentNum);
+void actual_inversions_segment(Segment *seg);
 void actual_inversions_done(void);
   /* safety.c will call these in this order: first start, then segment
    * for 0 or more segments (whose s.segments[segn].seg_inverted may
@@ -156,7 +168,7 @@ void actual_inversions_done(void);
 
 typedef struct TrackLocation TrackLocation;
 struct TrackLocation { /* transparent, and manipulable by trackloc_... fns */
-  SegmentNum segn; /* current segment */
+  Segment *seg; /* current segment */
   long into; /* distance from start of segment */
   unsigned backwards:1; /* if 1, into is positive and measured from end */
 };
@@ -193,8 +205,9 @@ const SegmentLinkInfo *trackloc_segmentlink(const TrackLocation *tloc,
 
 #define CLEAR_FORESIGHT_TIME 500 /*ms*/
 #define AUTOSTOP_MAXSPEED ((50 * SPEED_UNIT)/1000) /* 50 mm/s */
-#define AUTOSTOP_UNCERTAINTY 20
-#define ESTOP_UNCERTAINTY 300
+#define AUTOSTOP_UNCERTAINTY 20  /*mm*/
+#define ESTOP_UNCERTAINTY 300  /*mm*/
+#define ESTOP_DEADTIME    2000 /*ms*/
 
 #define SPEED_CLEAR_MULT SPEED_CALC_DIST(1,CLEAR_FORESIGHT_TIME,UP)