3 This file is part of the MSP Märklin suite
4 Copyright © 2010 Mikkosoft Productions, Mikko Rasa
5 Distributed under the GPL
18 AIControl::AIControl(Train &t, Controller *n):
21 target_speed(Control::continuous("speed", 0, 1000)),
27 train.signal_arrived.connect(sigc::mem_fun(this, &AIControl::arrived));
28 next_ctrl->signal_control_changed.connect(sigc::mem_fun(this, &AIControl::control_changed));
31 AIControl::~AIControl()
36 void AIControl::set_control(const string &n, float v)
40 if(v && !train.is_active())
41 train.set_active(true);
46 float approach_speed = 5*train.get_layout().get_catalogue().get_scale();
47 if(approach && target_speed.value>approach_speed)
48 next_ctrl->set_control("speed", approach_speed);
50 next_ctrl->set_control("speed", target_speed.value);
53 signal_control_changed.emit(target_speed);
56 next_ctrl->set_control(n, v);
59 const Controller::Control &AIControl::get_control(const string &n) const
64 return next_ctrl->get_control(n);
67 float AIControl::get_speed() const
69 return next_ctrl->get_speed();
72 bool AIControl::get_reverse() const
74 return next_ctrl->get_reverse();
77 float AIControl::get_braking_distance() const
79 return next_ctrl->get_braking_distance();
82 void AIControl::tick(const Time::TimeDelta &dt)
84 float scale = train.get_layout().get_catalogue().get_scale();
85 float rsv_dist = train.get_reserved_distance();
86 float brake_dist = next_ctrl->get_braking_distance();
87 float approach_margin = 50*scale;
88 float approach_speed = 5*scale;
89 float margin = 10*scale;
91 if(!blocked && rsv_dist<brake_dist+margin)
94 next_ctrl->set_control("speed", 0);
96 else if((!approach && rsv_dist<brake_dist*1.3+approach_margin) || (blocked && rsv_dist>brake_dist+margin*2))
100 if(target_speed.value>approach_speed)
101 next_ctrl->set_control("speed", approach_speed);
103 next_ctrl->set_control("speed", target_speed.value);
105 else if((blocked || approach) && rsv_dist>brake_dist*1.3+approach_margin*2)
109 next_ctrl->set_control("speed", target_speed.value);
114 if(!target_speed.value && !next_ctrl->get_speed() && train.is_active())
115 train.set_active(false);
118 void AIControl::control_changed(const Control &ctrl)
120 if(ctrl.name!="speed")
121 signal_control_changed.emit(ctrl);
124 void AIControl::arrived()
126 set_control("speed", 0);
129 } // namespace Marklin