train(t),
next_ctrl(n),
target_speed(Control::continuous("speed", 0, 1000)),
- blocked(false),
- approach(false)
+ state(NORMAL)
{
target_speed.set(0);
train.set_active(true);
target_speed.set(v);
- if(!blocked)
+ if(state!=BLOCKED)
{
float approach_speed = 5*train.get_layout().get_catalogue().get_scale();
- if(approach && target_speed.value>approach_speed)
+ if(state==APPROACH && target_speed.value>approach_speed)
next_ctrl->set_control("speed", approach_speed);
else
next_ctrl->set_control("speed", target_speed.value);
float approach_speed = 5*scale;
float margin = 10*scale;
- if(!blocked && rsv_dist<brake_dist+margin)
- {
- blocked = true;
- next_ctrl->set_control("speed", 0);
- }
- else if((!approach && rsv_dist<brake_dist*1.3+approach_margin) || (blocked && rsv_dist>brake_dist+margin*2))
+ State old_state = state;
+
+ if(state==FOLLOW && !train.get_preceding_train())
+ state = NORMAL;
+
+ if(rsv_dist<brake_dist+margin)
+ state = BLOCKED;
+ else if(rsv_dist>brake_dist+margin*2 && rsv_dist<brake_dist*1.3+approach_margin)
+ state = APPROACH;
+ else if(rsv_dist>brake_dist*1.3+approach_margin*2)
+ state = NORMAL;
+
+ if(state==NORMAL && train.get_preceding_train())
+ state = FOLLOW;
+
+ if(state!=old_state || state==FOLLOW)
{
- blocked = false;
- approach = true;
- if(target_speed.value>approach_speed)
- next_ctrl->set_control("speed", approach_speed);
+ float speed_limit = -1;
+ if(state==BLOCKED)
+ speed_limit = 0;
+ else if(state==APPROACH)
+ speed_limit = approach_speed;
+ else if(state==FOLLOW)
+ speed_limit = train.get_preceding_train()->get_speed();
+
+ if(speed_limit>=0 && target_speed.value>speed_limit)
+ next_ctrl->set_control("speed", speed_limit);
else
next_ctrl->set_control("speed", target_speed.value);
}
- else if((blocked || approach) && rsv_dist>brake_dist*1.3+approach_margin*2)
- {
- blocked = false;
- approach = false;
- next_ctrl->set_control("speed", target_speed.value);
- }
next_ctrl->tick(dt);