chiark / gitweb /
work at Redemption, checkin on return: reorganise things a bit and work on lay_train...
[trains.git] / hostside / safety.h
1 /**/
2
3 #ifndef SAFETY_H
4 #define SAFETY_H
5
6 /*========== basic types etc. ==========*/
7
8 typedef unsigned short TrainNum;
9 typedef unsigned short SegmentNum;
10 typedef unsigned short LocationNum;
11 typedef short TimeInterval;
12 typedef short Distance;
13 typedef char Speed; /* non-negative, units of 4mm/s */
14
15 /*========== state of the layout ==========*/
16
17 typedef struct {
18   SegmentNum foredetect;   /* train's detectable part is at most maxinto   */
19   Distance maxinto, uncertainty;   /*   into foredetect but train may be   */
20   unsigned                         /*   uncertainty less far advanced      */
21     backwards:1; /* train is moving backwards wrt its own front and back */
22   Speed speed;
23 } TrainState;
24
25 typedef struct {
26   unsigned
27     owned:1, /* this track segment is reserved for a train */
28     tr_backwards:1, /* train's motion is (would be) backwards wrt track */
29     pt_sideways:1, /* points are set to `alternative'. (no points?: 0) */
30     pt_moving:1, /* points have been told to change to pt_sideways */
31     cm_autostop:1, /* train should stop on detection */
32     cm_pointchange:1, /* points should change when they can */
33     seg_inverted:1, /* polarity is inverted! */
34     tr_updated:1; /* for use by safety.c:lay_train etc.; otherwise 0 */
35   TimeInterval until_here, /* ) nonnegative; */  /* ) always valid but */
36     until_detect;          /* ) 0 if already */  /* )  only meaningful */
37   TrainNum owner;                                /* )  iff owned       */
38   /*polarity?*/
39 } SegmentState;
40
41 typedef struct {
42   unsigned next_backwards:1;
43   SegmentNum next;
44   Distance dist;
45 } SegmentLinkInfo;
46
47 typedef struct {
48   unsigned invertible:1;
49   SegmentLink backwards, forwards, sideways;
50   const char *pname;
51 } SegmentInfo;
52
53 typedef struct {
54   Speed maxspeed;
55   Distance tail, detectable, head;
56   const char *pname;
57 } TrainInfo;
58
59 extern const TrainInfo info_trains[NUM_TRAINS];
60 extern const SegmentInfo info_segments[NUM_SEGMENTS];
61
62 typedef struct {
63   TrainState trains[NUM_TRAINS];
64   SegmentState segments[NUM_SEGMENTS];
65 } State;
66
67 extern State s;
68
69 /*========== safety.c ==========*/
70 /*
71  * safety.c is responsible for ensuring that things don't go
72  * physically wrong (eg, collisions, derailments, short circuits,
73  * etc.).
74  */
75
76 void safety_emergencystop(TranNum);
77   /* Callable directly in response to application command. */
78
79 void safety_requestspeed(TrainNum tran, long newspeed);
80   /* To be called only by the speed manager, thus indirectly from
81    * user request.
82    * Will result in a call to speedmanager_speedchange_notify (and of
83    * course to actual_setspeed.  Speed manager must apply accel/decel
84    * curve so that if safety.c agrees the command, the actual speed of
85    * the train changes straight away (at least for decel).
86    */
87
88 void safety_notify_detection(SegmentNum segn);
89   /* To be called by actual.c when new train detection occurs. */
90
91 /*========== speedmgr.c ==========*/
92
93 void speedmanager_speedchange_notify(TrainNum tran);
94   /* To be called only by safety.c, whenever speed is actually set.
95    * New speed has already been recorded in State. */
96
97 /*========== actual.c ==========*/
98 /* actual.c should only be called from safety.c.
99  * It is responsible for communicating with the PICs, including
100  * repeating the NMRA commands and redacting detection information.
101  */
102
103 void actual_setspeed(TrainNum tran);
104   
105 /*
106  *
107  * Entrypoints are:                  Called from, and as a result of:
108  *   actual_setspeed                    safety.c
109  *   actual_emergencystop               safety.c
110
111
112 /*========== utils.c ==========*/
113
114 typedef struct TrackLocation TrackLocation;
115 struct TrackLocation { /* transparent, and manipulable by trackloc_... fns */
116   SegmentNum segn; /* current segment */
117   long into; /* distance from start of segment */
118   unsigned backwards:1; /* if 1, into is positive and measured from end */
119 };
120
121 long trackloc_remaininseg(const TrackLocation *tloc);
122   /* Returns dist that tloc can advance before it goes into next segment. */
123
124 void trackloc_further(TrackLocation *tloc, long *remain_io);
125   /* Advances tloc, decrementing *remain_io, until either
126    * *remain_io becomes zero, or tloc->segn changes. */
127
128 void trackloc_reverse(TrackLocation *tloc);
129   /* Reverses tloc without changing its actual location. */
130
131 const SegmentLinkInfo *trackloc_segmentlink_near(const TrackLocation *tloc);
132 const SegmentLinkInfo *trackloc_segmentlink_far(const TrackLocation *tloc);
133
134 #endif /*SAFETY_H*/