]> git.tdb.fi Git - r2c2.git/blobdiff - source/libmarklin/aicontrol.cpp
Change the control system to separate speed and reverse
[r2c2.git] / source / libmarklin / aicontrol.cpp
index d5a29c0e540b2ceafbee82151db6e1153c5006ab..eefc7f87f230d586c2a083dbc0741ae0d4b1763d 100644 (file)
@@ -18,12 +18,14 @@ namespace Marklin {
 AIControl::AIControl(Train &t, ControlModel *n):
        train(t),
        next_model(n),
-       target_speed(TrainControl::continuous("speed", -1000, 1000)),
-       blocked(false)
+       target_speed(TrainControl::continuous("speed", 0, 1000)),
+       blocked(false),
+       approach(false)
 {
        target_speed.set(0);
 
        train.signal_arrived.connect(sigc::mem_fun(this, &AIControl::arrived));
+       next_model->signal_control_changed.connect(sigc::mem_fun(this, &AIControl::control_changed));
 }
 
 AIControl::~AIControl()
@@ -40,9 +42,15 @@ void AIControl::set_control(const string &n, float v)
 
                target_speed.set(v);
                if(!blocked)
-                       next_model->set_control("speed", target_speed.value);
-
-               signal_control_changed.emit(n, target_speed.value);
+               {
+                       float approach_speed = 5*train.get_layout().get_catalogue().get_scale();
+                       if(approach && target_speed.value>approach_speed)
+                               next_model->set_control("speed", approach_speed);
+                       else
+                               next_model->set_control("speed", target_speed.value);
+               }
+
+               signal_control_changed.emit(target_speed);
        }
        else
                next_model->set_control(n, v);
@@ -63,10 +71,7 @@ float AIControl::get_speed() const
 
 bool AIControl::get_reverse() const
 {
-       if(float ns = next_model->get_speed())
-               return ns<0;
-       else
-               return target_speed.value<0;
+       return next_model->get_reverse();
 }
 
 float AIControl::get_braking_distance() const
@@ -76,17 +81,31 @@ float AIControl::get_braking_distance() const
 
 void AIControl::tick(const Time::TimeDelta &dt)
 {
+       float scale = train.get_layout().get_catalogue().get_scale();
        float rsv_dist = train.get_reserved_distance();
-       float brake_dist = next_model->get_braking_distance()*1.15;
-       float margin = 25*train.get_layout().get_catalogue().get_scale();
+       float brake_dist = next_model->get_braking_distance();
+       float approach_margin = 50*scale;
+       float approach_speed = 5*scale;
+       float margin = 10*scale;
+
        if(!blocked && rsv_dist<brake_dist+margin)
        {
                blocked = true;
                next_model->set_control("speed", 0);
        }
-       else if(blocked && rsv_dist>brake_dist+margin*3)
+       else if((!approach && rsv_dist<brake_dist*1.3+approach_margin) || (blocked && rsv_dist>brake_dist+margin*2))
+       {
+               blocked = false;
+               approach = true;
+               if(target_speed.value>approach_speed)
+                       next_model->set_control("speed", approach_speed);
+               else
+                       next_model->set_control("speed", target_speed.value);
+       }
+       else if((blocked || approach) && rsv_dist>brake_dist*1.3+approach_margin*2)
        {
                blocked = false;
+               approach = false;
                next_model->set_control("speed", target_speed.value);
        }
 
@@ -96,10 +115,10 @@ void AIControl::tick(const Time::TimeDelta &dt)
                train.set_active(false);
 }
 
-void AIControl::control_changed(const string &n, float v)
+void AIControl::control_changed(const TrainControl &ctrl)
 {
-       if(n!="speed")
-               signal_control_changed.emit(n, v);
+       if(ctrl.name!="speed")
+               signal_control_changed.emit(ctrl);
 }
 
 void AIControl::arrived()