/*========== 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 */
* 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
* 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
* 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
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 */
};
#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)