]> git.tdb.fi Git - r2c2.git/commitdiff
Make the simulation independent of wall clock time
authorMikko Rasa <tdb@tdb.fi>
Sun, 9 Jun 2013 08:39:05 +0000 (11:39 +0300)
committerMikko Rasa <tdb@tdb.fi>
Sun, 9 Jun 2013 08:39:05 +0000 (11:39 +0300)
Layout now holds a Clock object, which keeps track of simulated absolute
time and can advance faster (or slower) than the system clock.

13 files changed:
source/libr2c2/aicontrol.cpp
source/libr2c2/aicontrol.h
source/libr2c2/clock.cpp [new file with mode: 0644]
source/libr2c2/clock.h [new file with mode: 0644]
source/libr2c2/layout.cpp
source/libr2c2/layout.h
source/libr2c2/train.cpp
source/libr2c2/train.h
source/libr2c2/trainai.h
source/libr2c2/trainrouter.cpp
source/libr2c2/trainrouter.h
source/libr2c2/trainstatus.cpp
source/libr2c2/trainstatus.h

index 6e1c4b16ab9f925471d0769f5bfa53b6ccbc70e6..97b7209cf47539f892ddfa5872b21d053eed949f 100644 (file)
@@ -52,7 +52,7 @@ void AIControl::message(const Message &msg)
                set_reverse(!reverse);
 }
 
-void AIControl::tick(const Time::TimeStamp &, const Time::TimeDelta &)
+void AIControl::tick(const Time::TimeDelta &)
 {
        float scale = train.get_layout().get_catalogue().get_scale();
        float rsv_dist = train.get_reserved_distance();
index 154a2ea5a78ee4ba1ddda9389a12ec47e4ebba4c..b0c53d59ce088becb05c853c708e711bcd6cedad 100644 (file)
@@ -34,7 +34,7 @@ public:
        bool get_reverse() const { return reverse; } 
 
        virtual void message(const Message &);
-       virtual void tick(const Msp::Time::TimeStamp &, const Msp::Time::TimeDelta &);
+       virtual void tick(const Msp::Time::TimeDelta &);
 
 private:
        void event(TrainAI &, const Message &);
diff --git a/source/libr2c2/clock.cpp b/source/libr2c2/clock.cpp
new file mode 100644 (file)
index 0000000..5f87c44
--- /dev/null
@@ -0,0 +1,21 @@
+#include "clock.h"
+
+using namespace Msp;
+
+namespace R2C2 {
+
+Clock::Clock():
+       rate(1)
+{ }
+
+void Clock::set_rate(float s)
+{
+       rate = s;
+}
+
+void Clock::tick(const Time::TimeDelta &dt)
+{
+       current_time += dt*rate;
+}
+
+} // namespace R2C2
diff --git a/source/libr2c2/clock.h b/source/libr2c2/clock.h
new file mode 100644 (file)
index 0000000..0fa5f59
--- /dev/null
@@ -0,0 +1,24 @@
+#ifndef LIBR2C2_CLOCK_H_
+#define LIBR2C2_CLOCK_H_
+
+#include <msp/time/timedelta.h>
+
+namespace R2C2 {
+
+class Clock
+{
+private:
+       Msp::Time::TimeDelta current_time;
+       float rate;
+
+public:
+       Clock();
+
+       void set_rate(float);
+       const Msp::Time::TimeDelta &get_current_time() const { return current_time; }
+       void tick(const Msp::Time::TimeDelta &);
+};
+
+} // namespace R2C2
+
+#endif
index efc1e0f74cbc97627de661b40caa4cc09dd6ac8e..46a43a8353fffd8cccc266f418dbaa7bb117bcd3 100644 (file)
@@ -39,7 +39,9 @@ Layout::Layout(Catalogue &c, Driver *d):
        catalogue(c),
        driver(d),
        next_turnout_id(0x800)
-{ }
+{
+       clock.set_rate(60);
+}
 
 Layout::~Layout()
 {
@@ -343,13 +345,15 @@ void Layout::tick()
                dt = t-last_tick;
        last_tick = t;
 
+       clock.tick(dt);
+
        for(set<Sensor *>::iterator i=sensors.get().begin(); i!=sensors.get().end(); ++i)
                (*i)->tick(dt);
        const set<Signal *> &signals = objects.get<Signal>();
        for(set<Signal *>::iterator i=signals.begin(); i!=signals.end(); ++i)
                (*i)->tick(dt);
        for(map<unsigned, Train *>::iterator i=trains.begin(); i!=trains.end(); ++i)
-               i->second->tick(t, dt);
+               i->second->tick(dt);
 }
 
 void Layout::emergency(const string &msg)
index 204a60f6d90b9e64718386cbeb384c3f511fa570..7c61c4fdecf8ead4c767efc77ba564849a417f65 100644 (file)
@@ -7,6 +7,7 @@
 #include <msp/time/timestamp.h>
 #include "geometry.h"
 #include "sensor.h"
+#include "clock.h"
 
 namespace R2C2 {
 
@@ -84,6 +85,7 @@ public:
 private:
        Catalogue &catalogue;
        Driver *driver;
+       Clock clock;
        std::string base;
        Storage<Object> objects;
        Storage<TrackChain> track_chains;
@@ -99,6 +101,7 @@ public:
        Catalogue &get_catalogue() const { return catalogue; }
        bool has_driver() const { return driver; }
        Driver &get_driver() const;
+       const Clock &get_clock() const { return clock; }
        const std::string &get_base() const { return base; }
 
        void add(Object &);
index d1fb4ed8a81b9608bb82827ccbf5071a3b395251..8cfa2d0ee4817158b11086ea318bdeef2c50db83 100644 (file)
@@ -136,11 +136,11 @@ void Train::set_active(bool a)
        active = a;
        if(active)
        {
-               stop_timeout = Time::TimeStamp();
+               stop_timeout = Time::zero;
                allocator.reserve_more();
        }
        else
-               stop_timeout = Time::now()+2*Time::sec;
+               stop_timeout = 2*Time::sec;
 }
 
 void Train::set_function(unsigned func, bool state)
@@ -289,18 +289,24 @@ void Train::reserve_more()
        allocator.reserve_more();
 }
 
-void Train::tick(const Time::TimeStamp &t, const Time::TimeDelta &dt)
+void Train::tick(const Time::TimeDelta &dt)
 {
-       if(!active && stop_timeout && t>=stop_timeout)
+       if(!active && stop_timeout)
        {
-               allocator.release_noncurrent();
-               stop_timeout = Time::TimeStamp();
+               stop_timeout -= dt;
+               if(stop_timeout<=Time::zero)
+               {
+                       allocator.release_noncurrent();
+                       stop_timeout = Time::TimeDelta();
+               }
        }
 
+       travel_time += dt;
+
        Driver &driver = layout.get_driver();
 
        for(list<TrainAI *>::iterator i=ais.begin(); i!=ais.end(); ++i)
-               (*i)->tick(t, dt);
+               (*i)->tick(dt);
        controller->tick(dt);
        float speed = controller->get_speed();
        bool moving = speed>0;
@@ -449,7 +455,7 @@ void Train::sensor_state_changed(Sensor &sensor, Sensor::State state)
 
                        if(travel_distance>0)
                        {
-                               float travel_time_secs = (Time::now()-last_entry_time)/Time::sec;
+                               float travel_time_secs = travel_time/Time::sec;
 
                                if(travel_time_secs>=2)
                                        speed_quantizer->learn(current_speed_step, travel_distance/travel_time_secs, travel_time_secs);
@@ -457,7 +463,7 @@ void Train::sensor_state_changed(Sensor &sensor, Sensor::State state)
                }
 
                last_entry_block = allocator.iter_for(*block);
-               last_entry_time = Time::now();
+               travel_time = Time::zero;
                pure_speed = true;
                accurate_position = true;
                overshoot_dist = 0;
index e3eebe1fc5d050d2d3b2a230eaa332416c909a1f..c0eb52e850006cd4ca48f41f1ad35dd77da227f3 100644 (file)
@@ -4,7 +4,7 @@
 #include <sigc++/signal.h>
 #include <sigc++/trackable.h>
 #include <msp/datafile/objectloader.h>
-#include <msp/time/timestamp.h>
+#include <msp/time/timedelta.h>
 #include "blockallocator.h"
 #include "controller.h"
 #include "sensor.h"
@@ -60,11 +60,11 @@ private:
        unsigned current_speed_step;
        bool speed_changing;
        bool reverse;
-       Msp::Time::TimeStamp stop_timeout;
+       Msp::Time::TimeDelta stop_timeout;
        unsigned functions;
 
        BlockIter last_entry_block;
-       Msp::Time::TimeStamp last_entry_time;
+       Msp::Time::TimeDelta travel_time;
        bool pure_speed;
        SpeedQuantizer *speed_quantizer;
        bool accurate_position;
@@ -123,7 +123,7 @@ public:
        const BlockAllocator &get_block_allocator() const { return allocator; }
        float get_reserved_distance() const;
 
-       void tick(const Msp::Time::TimeStamp &, const Msp::Time::TimeDelta &);
+       void tick(const Msp::Time::TimeDelta &);
 
        void save(std::list<Msp::DataFile::Statement> &) const;
 private:
index b040493ce1ea5d1c903745ddd60cbbda528dc83a..3f98613ded273808782d1244df60efb4f359f831 100644 (file)
@@ -43,7 +43,7 @@ public:
        virtual ~TrainAI();
 
        virtual void message(const Message &) { }
-       virtual void tick(const Msp::Time::TimeStamp &, const Msp::Time::TimeDelta &) { }
+       virtual void tick(const Msp::Time::TimeDelta &) = 0;
 };
 
 } // namespace R2C2
index d29438fef588b1107a70bddc620b7aa4a9bfb56e..a5e0d56543e13fab7082c5220c2b11f23ed96cce 100644 (file)
@@ -137,7 +137,7 @@ void TrainRouter::message(const Message &msg)
        }
 }
 
-void TrainRouter::tick(const Time::TimeStamp &, const Time::TimeDelta &)
+void TrainRouter::tick(const Time::TimeDelta &)
 {
        if(update_pending)
                create_plans(train.get_layout());
index 07afe2b722112bb4453b4b994ad7b517fff207f1..9938533cc86dfd36b03ffc3a4932626ac55d19a7 100644 (file)
@@ -63,7 +63,7 @@ public:
        bool is_destination(Track &) const;
 
        virtual void message(const Message &);
-       virtual void tick(const Msp::Time::TimeStamp &, const Msp::Time::TimeDelta &);
+       virtual void tick(const Msp::Time::TimeDelta &);
 
        void save(std::list<Msp::DataFile::Statement> &) const;
 
index a5f187faa26667294a710b655fcc6ec5999071a9..65c17f75418dec7c42296bb05b7686ed7cbf9f01 100644 (file)
@@ -16,7 +16,7 @@ TrainStatus::TrainStatus(Train &t):
        check();
 }
 
-void TrainStatus::tick(const Time::TimeStamp &, const Time::TimeDelta &)
+void TrainStatus::tick(const Time::TimeDelta &)
 {
        check();
 }
index 40ad5c711fb0322b352256d67afbeed6a0c96727..cc095c2b1cbaba3b41dc1107c4fe42dc900de0f1 100644 (file)
@@ -25,7 +25,7 @@ public:
        TrainStatus(Train &);
 
        const std::string &get_status() const { return status; }
-       void tick(const Msp::Time::TimeStamp &, const Msp::Time::TimeDelta &);
+       void tick(const Msp::Time::TimeDelta &);
 private:
        void check();
 };