From: ian Date: Mon, 28 Mar 2005 16:31:32 +0000 (+0000) Subject: hostside safety.c compiles but safety does not link X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ijackson/git?a=commitdiff_plain;h=f72ddf59d73fdf1ede3e66ac324439756b41c3a5;p=trains.git hostside safety.c compiles but safety does not link --- diff --git a/hostside/safety.c b/hostside/safety.c index c7181b5..935a0ab 100644 --- a/hostside/safety.c +++ b/hostside/safety.c @@ -2,6 +2,7 @@ */ #include +#include #include "layoutinfo.h" #include "safety.h" @@ -28,36 +29,37 @@ typedef struct { static void lay_train_pass(LayTrainState *l, TrackLocation tloc, long advance, - unsigned backwards, long speed, + long speed, unsigned backwards, unsigned check_clash) { + State *s= &safety_state; SegmentNum segn; SegmentState *seg; const SegmentInfo *segi; - long overall, remain; - int *invert_likehere, *invert_unlikehere, train_inverted_here; - TrainState *tra= &s.trains[l->tran]; + long overall, remain, dist_until, time_until; + int *invert_likehere, train_inverted_here; + TrainState *tra= &s->trains[l->tran]; if (l->ec) return; segn= tra->foredetect; - seg= &s.segments[segn]; + seg= &s->segments[segn]; remain= overall= advance + speed * SPEED_CLEAR_MULT; for (;;) { segn= tloc.segn; - seg= &s.segments[segn]; + seg= &s->segments[segn]; segi= &info_segments[segn]; if (check_clash) { if (seg->tr_updated) { - l->ec= safety_problem(tloc.segn, l->tran, "self-collision"); + l->ec= safety_problem(l->tran, tloc.segn, "self-collision"); return; } if (seg->owned) { if (seg->owner != l->tran) { - l->ec= safety_problem(tloc.segn, l->tran, seg->owner, "collision" - " with %s", info_trains[seg->owner].pname); + l->ec= safety_problem(l->tran, tloc.segn, "collision with %s", + info_trains[seg->owner].pname); return; } seg_clear_stale(seg); @@ -77,7 +79,7 @@ static void lay_train_pass(LayTrainState *l, (*invert_likehere)++; } else { if (*invert_likehere < 0) { - l->ec= safety_problem(l->tran, NOTA(SegmentNum), "train requires" + l->ec= safety_problem(l->tran, NOTA(Segment), "train requires" " noninvertible segments with opposite polarity:" " @%s, @%s", segi->pname, info_segments[l->invert_forcer].pname); @@ -90,8 +92,7 @@ static void lay_train_pass(LayTrainState *l, } dist_until= (overall - remain) - advance; - time_until= !speed ? 0 : - (SPEED_FACTOR * dist_until) / speed; + time_until= !speed ? 0 : SPEED_CALC_TIME(speed, dist_until, DOWN); *(check_clash ? &seg->until_here : &seg->until_detect)= time_until; if (!remain) break; @@ -100,6 +101,7 @@ static void lay_train_pass(LayTrainState *l, } static void lay_train_inversions(LayTrainState *l) { + State *s= &safety_state; SegmentNum segn; SegmentState *seg; const SegmentInfo *segi; @@ -112,7 +114,7 @@ static void lay_train_inversions(LayTrainState *l) { actual_inversions_start(); - for (segn=0, seg=s->segs, segi=info_segments; + for (segn=0, seg=s->segments, segi=info_segments; segn <= NUM_SEGMENTS; segn++, seg++) { if (!seg->tr_updated) continue; @@ -120,37 +122,36 @@ static void lay_train_inversions(LayTrainState *l) { seg_be_inverted= train_be_inverted ^ seg->tr_backwards; assert(!(seg_be_inverted && !segi->invertible)); seg->seg_inverted= seg_be_inverted; - actual_inversions_segment(); + actual_inversions_segment(segn); } actual_inversions_done(); } static void lay_train_done(LayTrainState *l) { + State *s= &safety_state; SegmentNum segn; SegmentState *seg; - for (segn=0, seg=s->segs; + for (segn=0, seg=s->segments; segn <= NUM_SEGMENTS; segn++, seg++) { - if (seg->tran == l->tran) { + if (seg->owner == l->tran) { if (!seg->tr_updated) seg_clear_stale(seg); seg->tr_updated= 0; } assert(!seg->tr_updated); - assert(seg->tr_here_future >= seg->tr_here_now); - assert(seg->tr_detect_future >= seg->tr_detect_now); - assert(seg->tr_detect_future >= seg->tr_here_future); - assert(seg->tr_detect_now >= seg->tr_here_now); + assert(seg->until_detect >= seg->until_here); } } static ErrorCode lay_train(TrainNum tran, long added_slop) { State *s= &safety_state; TrainState *tra= &s->trains[tran]; - TrainInfo *trai= info_trains[tran]; + const TrainInfo *trai= &info_trains[tran]; + SegmentNum segn; SegmentState *seg; TrackLocation tloc; - long head, future; + long head, headslop, tail, taildet; LayTrainState l; segn= tra->foredetect; @@ -158,7 +159,7 @@ static ErrorCode lay_train(TrainNum tran, long added_slop) { tloc.segn= segn; tloc.into= tra->maxinto; - tloc.backwards= seg->tr_backwards ^ backwards; + tloc.backwards= seg->tr_backwards ^ tra->backwards; l.tran= tran; l.ec= 0; @@ -180,15 +181,15 @@ static ErrorCode lay_train(TrainNum tran, long added_slop) { * whether the train clashes with itself (ie, fail if we find * segment with same train and tr_updated set). */ - lay_train(&l, tloc, tra->speed, headslop, 1); - lay_train(&l, tloc, tra->speed, 0, 0); + lay_train_pass(&l, tloc, headslop, tra->speed, 0, 1); + lay_train_pass(&l, tloc, 0, tra->speed, 0, 0); trackloc_reverse(&tloc); seg->tr_updated= 0; /* we're about to do this one again */ tail= tra->backwards ? trai->head : trai->tail; - taildet= tra->detectable + tail; + taildet= trai->detectable + tail; - lay_train(&l, tloc, 0, taildet, 1); + lay_train_pass(&l, tloc, taildet, 0, 1, 1); lay_train_inversions(&l); lay_train_done(&l); @@ -199,7 +200,8 @@ static ErrorCode lay_train(TrainNum tran, long added_slop) { static void setspeed(TrainNum tran, Speed newspeed) { /* does not lay the train, caller must do that (or have done it, * in which case they should already have set tra->speed). */ - TrainState *tra = s->trains[tran]; + State *s= &safety_state; + TrainState *tra= &s->trains[tran]; tra->speed= newspeed; actual_setspeed(tran); @@ -207,15 +209,18 @@ static void setspeed(TrainNum tran, Speed newspeed) { } void safety_notify_detection(SegmentNum segn) { - State *s = &safety_state; - SegmentState *seg = s->segments[segn]; - TrainNum tran = segs->owner; - TrainState *tra = s->trains[tran]; + State *s= &safety_state; + SegmentState *seg= &s->segments[segn]; + TrainNum tran= seg->owner; + TrainState *tra= &s->trains[tran]; + ErrorCode ec; TrackLocation tloc; - if (seg->detectable_now) return; - if (!seg->detectable_future) - safety_panic(NOTA(TrainNum), segn, "unexpected detection"); + if (!seg->owned) + safety_panic(NOTA(Train), segn, "unexpected detection"); + + if (!seg->until_detect) + return; tloc.segn= segn; tloc.into= 0; @@ -239,24 +244,28 @@ void safety_notify_detection(SegmentNum segn) { ec= lay_train(tran, 0); if (ec) { - logmsg(tran, segn, "emergency stop"); + logmsg(ec, tran, segn, "emergency stop"); safety_emergencystop(tran); } } -void safety_emergencystop(TranNum) { +void safety_emergencystop(TrainNum tran) { + State *s= &safety_state; ErrorCode ec; + TrainState *tra= &s->trains[tran]; tra->speed= 0; actual_emergencystop(tran); ec= lay_train(tran, ESTOP_UNCERTAINTY); - if (ec) safety_panic(tran, segn, "emergency stop forbidden!"); - speedmanager_speedchange_notify(tran, tra->backwards); + if (ec) safety_panic(tran, NOTA(Segment), "emergency stop forbidden!"); + speedmanager_speedchange_notify(tran); } void safety_requestspeed(TrainNum tran, long newspeed) { + State *s= &safety_state; long oldspeed; - TrainState *tra = s->trains[tran]; + TrainState *tra= &s->trains[tran]; + ErrorCode ec; oldspeed= tra->speed; tra->speed= newspeed; @@ -265,18 +274,18 @@ void safety_requestspeed(TrainNum tran, long newspeed) { if (ec) { if (oldspeed && oldspeed < newspeed) { - logmsg(tran, NOTA(SegmentNum), "countermanded acceleration", - " from %l to %l", oldspeed, newspeed); + logmsg(ec, tran, NOTA(Segment), "countermanded acceleration" + " from %ld to %ld", oldspeed, newspeed); } else if (oldspeed) { - safety_panic(tran, NOTA(SegmentNum), "deceleration forbidden!" - " (from %l to %l", oldspeed, newspeed); + safety_panic(tran, NOTA(Segment), "deceleration forbidden!" + " (from %ld to %ld", oldspeed, newspeed); } else { - logmsg(tran, NOTA(SegmentNum), "countermanded motion start"); + logmsg(ec, tran, NOTA(Segment), "countermanded motion start"); } setspeed(tran, oldspeed); ec= lay_train(tran, 0); if (ec) - safety_panic(tran, NOTA(SegmentNum), "countermanding" + safety_panic(tran, NOTA(Segment), "countermanding" " speed change insufficient!"); return; } diff --git a/hostside/safety.h b/hostside/safety.h index 3b375b0..0bc5269 100644 --- a/hostside/safety.h +++ b/hostside/safety.h @@ -8,9 +8,20 @@ /*========== more basic types etc. ==========*/ -typedef short TimeInterval; +typedef short TimeInterval; /*ms*/ typedef int ErrorCode; +/*---------- units and scales ----------*/ + +/* + * Distances are in mm. + * Times are in ms. + * Speeds are in fixed point: unit is 1/SPEED_UNIT m/s + */ + +#define SPEED_SHIFT 7 +#define SPEED_UNIT (1L<