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