sub calcwait ($$) {
my ($step,$wholetime) = @_;
return 0 if $step<0 || $step>=$steps;
- return $wholetime * 1000.0 *
+ return $wholetime *
($speed[$step+1] - $speed[$step]) / $max;
}
for ($step=0; $step<$nxt; $step++) {
- printf "train %s step %d=%d %d/%d\n",
- "'$train'", $step, $speed[$step]*1e6,
+ printf "train %s step %d=%f %f/%f\n",
+ "'$train'", $step, $speed[$step]*1e3,
calcwait($step-1,'$acceltime'),
calcwait($step,'$deceltime')
or die $!;
if (!tra->pname || !tra->foredetect ||
!tra->foredetect->i || !tra->foredetect->i->pname)
continue;
- printf("train %s at %s%s:%d+-%d\n",
+ printf("train %s at %s%s:%f+-%f\n",
tra->pname, tra->backwards ? "-" : "",
tra->foredetect->i->pname, tra->maxinto, tra->uncertainty);
}
[0-9]{0,8} { record_yylval.num= strtoul(yytext,0,10); return NUM; }
[0-9]{9} { record_yyerror("number too long"); }
+[0-9][0-9]*\.[0-9]* { record_yylval.dbl= strtod(yytext,0); return DBL; }
[-+:=~/] { record_yylval.name= 0; return yytext[0]; }
FeaturesFeature *feature;
FeaturesAddr *feataddr;
int num;
+ double dbl;
}
%token <name> TRAIN FEATURE SEG IS AT HAS STEP HOME END IDENT FEATLETTER
%token <name> NL
%token <num> NUM
+%token <dbl> DBL
%type <name> ident
%type <train> train
%type <seg> seg
%type <num> backwards
+%type <dbl> dbl
%type <feature> feature
%type <feataddr> feataddr
| line NL { record_tempzone_clear(); } file
line: /* empty */
- | TRAIN train IS NUM NUM '+' NUM '+' NUM
+ | TRAIN train IS NUM dbl '+' dbl '+' dbl
{ if ($2) record_train_is($2,$4,$5,$7,$9);
}
- | TRAIN train AT backwards seg ':' NUM '+' '-' NUM
+ | TRAIN train AT backwards seg ':' dbl '+' '-' dbl
{ if ($2) record_train_at($2,$4,$5,$7,$10);
}
| TRAIN train HOME { cur_train=$2; } segments
{
}
- | TRAIN train STEP NUM '=' NUM NUM '/' NUM
+ | TRAIN train STEP NUM '=' dbl dbl '/' dbl
{ if (!trains) record_train_step_count();
else if ($2) record_train_step($2,$4,$6,$7,$9);
}
segments: { cur_train= (void*)-1; }
| backwards seg { record_train_home(cur_train,$1,$2); } segments
+
ident: TRAIN | SEG | IS | AT | HAS | STEP | HOME | END
| IDENT | FEATLETTER
+dbl: DBL
+ | NUM { $$= $1 }
seg: ident { $$= record_pname2seg($1); }
train: ident { $$= record_pname2train($1); }
curvebufused++;
new->step= step;
- new->speed= speed * 1e-6 * SPEED_UNIT;
- new->upwait= upw * 1e-3;
- new->downwait= downw * 1e-3;
+ new->speed= speed;
+ new->upwait= upw;
+ new->downwait= downw;
}
static int speedcurveentry_compare(const void *av, const void *bv) {
}
if (d->owner)
- d->until_detect= 1;
+ d->until_detect= 1e-3;
if (d->i->n_poscombs>1) {
d->movposcomb= -1;
/*========== more basic types etc. ==========*/
-typedef short TimeInterval; /*ms*/
+typedef double TimeInterval; /*s*/
/*---------- units and scales ----------*/
/*
* Distances are in mm.
- * Times are in ms.
- * Speeds are in fixed point: unit is 1/SPEED_UNIT m/s
- *
- * To calculate with speeds and times without using floating point
- * it turns out that we can cope with distances of up to
- * 2^(31-SPEED_SHIFT) mm
+ * Times are generally in s.
*/
-#define SPEED_SHIFT 16 /* units of 15um/s, max distance 2^15mm =~ 32m */
-#define SPEED_UNIT (1L<<SPEED_SHIFT) /* ms/mm */
-
/*========== state of the layout ==========*/
typedef struct MovPosChange MovPosChange;
typedef struct {
int step;
- long speed;
+ Speed speed;
TimeInterval upwait, downwait; /* between this insn and next one */
} SpeedCurveEntry;
/*---------- calculations with fixed point speeds ----------*/
-#define DIVIDE_ROUNDING_UP(num,den) (((num) + (den) - 1) / (den))
-#define DIVIDE_ROUNDING_DOWN(num,den) ( (num) / (den))
-
-#define SPEED_CALC_TIME(speed,dist,round) \
- DIVIDE_ROUNDING_##round((dist) * SPEED_UNIT, (speed))
-
-#define SPEED_CALC_DIST(speed,time,round) \
- DIVIDE_ROUNDING_##round((time) * (speed), SPEED_UNIT)
+#define SPEED_CALC_TIME(speed,dist,round) ((dist) / ((speed)+1e-6))
+#define SPEED_CALC_DIST(speed,time,round) ((time) * (speed))
/*---------- safety margin parameters ----------*/
#define CLEAR_FORESIGHT_TIME 500 /*ms*/
-#define AUTOSTOP_MAXSPEED ((50 * SPEED_UNIT)/1000) /* 50 mm/s */
+#define AUTOSTOP_MAXSPEED 50.0 /*mm/s*/
#define AUTOSTOP_UNCERTAINTY 20 /*mm*/
#define ESTOP_UNCERTAINTY 300 /*mm*/
#define ESTOP_DEADTIME 2000 /*ms*/
+#define TIMEINTERVAL2MS(ti) ((ti) * 1000.0)
#define SPEED_CLEAR_MULT SPEED_CALC_DIST(1,CLEAR_FORESIGHT_TIME,UP)
#endif /*SAFETY_H*/
toev_stop(&tra->accel.more);
tra->accel.more.callback= estop_done;
- tra->accel.more.duration= ESTOP_DEADTIME;
+ tra->accel.more.duration= TIMEINTERVAL2MS(ESTOP_DEADTIME);
toev_start(&tra->accel.more);
}
if (tra->accel.target > tra->accel.commanded) {
tra->accel.commanded++;
- tra->accel.more.duration= tra->accel.curve[tra->accel.commanded].upwait;
+ tra->accel.more.duration=
+ TIMEINTERVAL2MS(tra->accel.curve[tra->accel.commanded].upwait);
newspeed= tra->accel.curve[tra->accel.commanded].speed;
} else if (tra->accel.target < tra->accel.commanded) {
newspeed= tra->accel.curve[tra->accel.commanded].speed;
tra->accel.commanded--;
- tra->accel.more.duration= tra->accel.curve[tra->accel.commanded].downwait;
+ tra->accel.more.duration=
+ TIMEINTERVAL2MS(tra->accel.curve[tra->accel.commanded].downwait);
} else {
return;
}
if (curve[found].speed < speed && speed != INT_MAX)
logmsg(EC_Invalid, tra,0,
- "requested speed %ld excessive; capping at %ld",
+ "requested speed %ld excessive; capping at %f",
speed, curve[found].speed);
changereq_internal(tra, found, 0);
($comb / $featr->{Weight}) % $featr->{Posns});
}
o("$delim\n");
- o(sprintf " { %-7s%4d",
+ o(sprintf " { %-7s%7.3f",
'"'.$pi.'",',
$segr->{Dist}[$comb]);
for ($end=0; $end<2; $end++) {
typedef int TrainNum;
typedef int SegmentNum;
typedef long MovPosComb;
-typedef long Speed;
typedef int BoardObject;
typedef int Small;
-typedef int Distance;
typedef short SegmentNumInMap;
+typedef double Speed;
+typedef double Distance;
+
typedef enum {
mfk_none,
mfk_point