if (!tra->pname || !tra->foredetect ||
!tra->foredetect->i || !tra->foredetect->i->pname)
continue;
- printf("train %s at %s%s\n",
+ printf("train %s at %s%s:%d-+%d\n",
tra->pname, tra->backwards ? "-" : "",
- tra->foredetect->i->pname);
+fixme tra->backwards is wrong
+ need to provide both tra->backwards and tr_backwards
+ tra->foredetect->i->pname, tra->mininto, tra->uncertainty);
}
FOR_SEG {
if (seg->i != segi || !segi->pname ||
| TRAIN train IS NUM NUM '+' NUM '+' NUM
{ if ($2) record_train_is($2,$4,$5,$7,$9);
}
- | TRAIN train AT backwards seg
- { if ($2) record_train_at($2,$4,$5);
+ | TRAIN train AT backwards seg ':' NUM '+' '-' NUM
+ { if ($2) record_train_at($2,$4,$5,$7,$10);
}
| TRAIN train AT backwards seg ':' NUM '+' '-' NUM
{ if ($2) record_train_at($2,$4,$5,$7,$10);
tra->tail= tail;
}
-void record_train_at(Train *tra, int backw, Segment *seg, int maxi, int unc) {
+void record_train_at(Train *tra, int backw, Segment *seg, int mini, int unc) {
tra->foredetect= seg;
tra->maxinto= maxi;
tra->uncertainty= unc;
tra->pname= *trap= pname;
tra->addr= -1;
tra->foredetect= 0;
+ tra->uncertainty= tra->maxinto= 0;
tra->backwards= 0;
for (step=0; step<=SPEEDSTEPS; step++)
tra->speedcurve[step]= -1;
return 0;
}
-void resolve_motioncheck(void) {
- SEG_IV;
- assert(sta_state == Sta_Finalising);
+static int rtf_nextseg(TrackLocation *t, struct TrackAdvanceContext *c,
+ MovPosComb *mpc_io, Segment *before) {
+ if (t->seg->owner != before->owner)
+ return -1;
+ t->seg->owner->foredetect= t->seg;
+}
+
+static void resolve_train_finalise(Train *tra) {
+ TrackLocation t;
+ TrackAdvanceContext tc;
+
+ t.seg= tra->foredetect;
+ t.remain= 0;
+ t.backwards= t.seg->tr_backwards;
+ tc.distance= INT_MAX;
+ tc.nextseg= rtf_nextseg;
+ tc.getmovpos= 0;
+ tc.trackend= 0;
+
+ trackloc_advance(&t,&tc);
+
- FOR_SEG
- if (seg->moving) return;
- FOR_SEG {
- if (seg->res_detect) {
+ for (;;) {
+
+
Segment *notify, *onwards;
const SegPosCombInfo *pci;
const SegmentLinkInfo *link;
assert(notify->movposcomb >= 0);
pci= ¬ify->i->poscombs[notify->movposcomb];
- link= notify->tr_backwards ? &pci->backwards : &pci->forwards;
+ link= &pci->link[notify->tr_backwards];
if (!SOMEP(link->next)) break;
onwards= &segments[link->next];
notify= onwards;
}
+
+
+void resolve_motioncheck(void) {
+ SEG_IV;
+ assert(sta_state == Sta_Finalising);
+
+ FOR_SEG
+ if (seg->moving) return;
+
+ FOR_SEG
+ if (seg->res_detect) {
+ assert(seg->owner);
+ seg->owner->foredetect= seg; /* initial guess */
+ }
+
+
+ FOR_TRA
+ resolve_train_finalise(tra);
+
+ FOR_SEG {
+ if (seg->res_detect) {
safety_notify_detection(notify);
}
u.problem_callback= ppc;
u.problem_callback_u= ppcu;
- trackloc_set_maxinto(&u.fdet, foredet, foredet->tr_backwards);
- trackloc_set_maxinto(&u.tail, foredet, !foredet->tr_backwards);
+ u.fdetc.getmovpos= pred_getmovpos;
+ u.tailc.getmovpos= pred_getmovpos;
+
+ trackloc_set_exactinto(&u.fdet, &u.fdetc, foredet, foredet->tr_backwards,
+ tra->maxinto);
+ u.tail= u.fdet;
+ ec= trackloc_reverse_exact(&u.tail, &u.tailc); assert(!ec);
/* find the train's tail and mark it present */
- u.tailc.distance= tra->detectable + (tra->backwards ? tra->head : tra->tail);
+ u.tailc.distance= tra->detectable + (tra->backwards ? tra->head : tra->tail)
+ + tra->uncertainty + MARGIN_TAIL;
u.tailc.nextseg= initpresent_nextseg;
- u.tailc.getmovpos= pred_getmovpos;
u.tailc.trackend= pred_trackend_panic;
u.tailc.u= &u;
void safety_notify_detection(Segment *seg) {
Train *tra;
+ TrackLoc tloc;
ErrorCode ec;
if (seg->det_ignore) return;
if (!seg->det_expected)
safety_panic(0,seg, "unexpected detection");
-
+ if (seg->movposcomb < 0)
+ safety_panic(tra,seg, "track route not set and train has arrived");
+
tra= seg->owner;
tra->foredetect= seg;
- if (tra->foredetect->movposcomb < 0)
- safety_panic(tra,seg, "track route not set and train has arrived");
+ tra->uncertainty= tra->maxinto=
+ seg->i->poscombs[seg->movposcomb].dist;
ec= predict_confirm(tra, 0, detection_report_problem, 0);
if (!ec) return;
/* Location: */
struct Segment *foredetect;
+ Distance maxinto, uncertainty;
unsigned
backwards:1, /* train is moving backwards wrt its own front and back */
/*---------- safety margin parameters ----------*/
#define MARGIN_NOSE 6
+#define MARGIN_TAIL 6
#define MARGIN_SPEED 1.2
#if 0
static void decel_done(TimeoutEvent *toev) {
Train *tra= (void*)((char*)toev - offsetof(Train, speed.decel));
tra->speed.speed= tra->speedcurve[tra->speed.step];
+ if (tra->sigstopping) {
+ assert(!tra->speed.step);
+ resolve_train_
}
static const SpeedRange *stop_info(Train *tra, double speed) {
if (left_to_go <= 0) {
toev_stop(&tra->speed.decel);
- return tra->speed.speed= tra->speedcurve[tra->speed.step];
+ decel_done(&tra->speed.decel);
+ return tra->speed.speed;
}
v2= tra->speed.speed;
toev_stop(&tra->speed.decel);
tra->speed.speed= vtarg;
tra->speed.try_speed= -1;
+ tra->sigstopping= 0;
xmit(tra);
return 0;
}