lay_train_checkclash2(
static void lay_train(ErrorCode *ec, TrainNum tran,
- TrackLocation tloc, long advance,
- unsigned pass) {
+ TrackLocation tloc, long into,
+ unsigned backwards, long speed) {
/* pass 0: update actual train location, check for train clashing
* with itself (ie, fail if we find segment with same train and
* tr_updated set.
if (*ec) return;
- remain= overall= advance + tra->speed * SPEED_CLEAR_MULT;
+ segn= tra->segn;
+ seg= &s->segs[segn];
+ tloc.segn= segn;
+ tloc.into= into;
+ tloc.backwards= seg->tr_backwards ^ backwards;
+
+ remain= overall= advance + speed * SPEED_CLEAR_MULT;
for (;;) {
- seg= &s->segs[tloc.segn];
- segi= &info_segment[tloc.segn];
+ segn= tloc.segn;
+ seg= &s->segs[segn];
+ segi= &info_segment[segn];
- if (pass==0) {
+ if (check_clash) {
if (seg->tr_updated) {
*ec= safety_problem(tloc.segn, tran, tran, "collision with itself");
return;
}
seg->owned= 1;
- seg->owner_backwards= tloc.backwards;
+ seg->owner_backwards= tloc.backwards ^ backwards;
seg->tr_updated= 1;
seg->tran= tran;
- seg->tr_justarrived= pass==0 && remain && tra->justarrived;
-
- lay_train_checkclash(ec, trackloc_segmentlink_near());
- if (!remain && tra->justarrived) {
-
-
- if (tloc.into <= JUSTARRIVED_INTOMAX) {
- seg->tr_justarrived= 1;
- } else {
- lay_train_checkclash(&ec, trackloc_segmentlink_far());
- }
-
-
dist_until= (overall - remain) - advance;
time_until= (SPEED_FACTOR * dist_until) / tra->speed;
*(pass==0 ? &seg->until_here : &seg->until_detect)= time_until;
segn= tra->foredetect;
seg= &s->seg[segn];
- tloc.segn= segn;
- tloc.into= 0;
- tloc.backwards= seg->tr_backwards;
-
- tloc.into= trackloc_remaininseg(&tloc);
- if (tra->justarrived && tloc.into > JUSTARRIVED_DIST)
- tloc.into= JUSTARRIVED_DIST;
-
head= tra->backwards ? trai->tail : trai->head;
lay_train(tran, &ec, tloc, head, 0,1);
ec= 0;
- lay_train(&ec, tran, tloc, head, 0,1);
- lay_train(&ec, tran, tloc, 0, 1,0);
+ lay_train(&ec, tran, tloc, head, 0);
+ lay_train(&ec, tran, tloc, 0, 1);
lay_train_done(tran);
if (ec) return ec;
SegmentState *seg = s->seg[segn];
TrainNum tran = segs->owner;
TrainState *tra = s->tras[tran];
+ TrackLocation tloc;
if (seg->detectable_now) return;
if (!seg->detectable_future)
safety_panic(segn, NONE, "unexpected detection");
- tra->foredetect= segn;
- tra->justarrived= 0;
+ tloc.segn= segn;
+ tloc.into= 0;
+ tloc.backwards= seg->tr_backwards;
+ tra->foredetect= segn;
+ tra->maxinto= trackloc_remaininseg(&tloc);
+
if (seg->autostop) {
- actual_setspeed(tran, 0);
- tra->justarrived= 1;
+ seg->autostop= 0;
+ speedmanager_setspeed(tran, 0);
+ if (tra->maxinto > AUTOSTOP_UNCERTAINTY)
+ tra->maxinto= AUTOSTOP_UNCERTAINTY;
}
-
+ tra->uncertainty= tra->maxinto;
+
ec= safety_train_changed(tran);
if (ec) {
logmsg(tran, segn, "emergency stop");