3 This file is part of R²C²
4 Copyright © 2010-2011 Mikkosoft Productions, Mikko Rasa
5 Distributed under the GPL
18 AIControl::AIControl(Train &t):
22 pending_reverse(false),
26 train.signal_arrived.connect(sigc::mem_fun(this, &AIControl::arrived));
29 void AIControl::set_target_speed(float s)
31 if(s && !train.is_active())
32 train.set_active(true);
36 signal_event.emit(Message("target-speed-changed", target_speed));
39 void AIControl::set_reverse(bool r)
42 if(train.get_controller().get_speed())
47 train.set_control("reverse", reverse);
48 signal_event.emit(Message("reverse-changed", reverse));
52 void AIControl::message(const Message &msg)
54 if(msg.type=="set-target-speed")
55 set_target_speed(msg.value.value<float>());
56 else if(msg.type=="set-reverse")
57 set_reverse(msg.value.value<bool>());
58 else if(msg.type=="toggle-reverse")
59 set_reverse(!reverse);
62 void AIControl::tick(const Time::TimeStamp &, const Time::TimeDelta &)
64 float scale = train.get_layout().get_catalogue().get_scale();
65 float rsv_dist = train.get_reserved_distance();
66 float brake_dist = train.get_controller().get_braking_distance();
67 float approach_margin = 50*scale;
68 float approach_speed = 5*scale;
69 float margin = 1*scale;
71 State old_state = state;
73 if(state==FOLLOW && !train.get_preceding_train())
76 if(rsv_dist<brake_dist+margin)
78 else if(rsv_dist>brake_dist+margin*2 && rsv_dist<brake_dist*1.3+approach_margin)
80 else if(rsv_dist>brake_dist*1.3+approach_margin*2)
83 if(state==NORMAL && train.get_preceding_train())
86 if(state!=old_state || state==FOLLOW || need_update)
88 float speed_limit = -1;
91 else if(state==APPROACH)
92 speed_limit = approach_speed;
93 else if(state==FOLLOW && train.get_preceding_train()->is_active())
94 speed_limit = train.get_preceding_train()->get_speed();
96 if(speed_limit>=0 && target_speed>speed_limit)
97 train.set_control("speed", speed_limit);
99 train.set_control("speed", target_speed);
104 if(pending_reverse!=reverse && !train.get_controller().get_speed())
106 reverse = pending_reverse;
107 train.set_control("reverse", reverse);
110 if(!target_speed && !train.get_controller().get_speed() && train.is_active())
111 train.set_active(false);
114 void AIControl::arrived()