00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #ifndef __J2K__Train__Model_CPP__
00011 #define __J2K__Train__Model_CPP__
00012
00013 #include <math.h>
00014 #include "model.hh"
00015
00016
00017 const char Model_track::next_sector_[][][] =
00018 {
00019 { { 2, -1 }, { 16,-1 } },
00020 { { 3, 5 }, { 1, -1 } },
00021 { { 4, -1 }, { 2, -1 } },
00022 { { 7, -1 }, { 3, -1 } },
00023 { { 6, -1 }, { 2, -1 } },
00024 { { 7, -1 }, { 5, -1 } },
00025 { { 8, -1 }, { 4, 6 } },
00026 { { 9, -1 }, { 7, -1 } },
00027 { { 10,-1 }, { 8, -1 } },
00028 { { 13, 11}, { 9, -1 } },
00029 { { 12, -1}, {10, -1 } },
00030 { { 15, -1}, {11, -1 } },
00031 { { 14, -1}, {10, -1 } },
00032 { { 15, -1}, {13, -1 } },
00033 { { 16, -1}, {14, 12 } },
00034 { { 1, -1}, {15, -1 } }
00035 };
00036
00037 const char Model_track::relevant_switch_[] =
00038 {
00039 -1,
00040 3,
00041 -1,
00042 -1,
00043 -1,
00044 -1,
00045 2,
00046 -1,
00047 -1,
00048 1,
00049 -1,
00050 -1,
00051 -1,
00052 -1,
00053 0,
00054 -1
00055 };
00056
00057 static const double Speed_scale = 1.0 / ( 14.0 * 4 );
00058
00059 void Model_track::position( double speed,
00060 double& pos,
00061 char& sector)
00062 {
00063 char s;
00064 int sign;
00065 pos += speed * Speed_scale;
00066 if (pos < 0.0) {
00067 pos += 1.0;
00068 if ( relevant_switch_[sector-1] != -1 ) {
00069 sector = next_sector_[sector-1][1][relevant_switch_[sector-1]];
00070 } else {
00071 sector = next_sector_[sector-1][1][0];
00072 }
00073 } else if( pos > 1.0 ) {
00074 pos -= 1.0;
00075 if ( relevant_switch_[sector-1] != -1 ) {
00076 sector = next_sector_[sector-1][0][relevant_switch_[sector-1]];
00077 } else {
00078 sector = next_sector_[sector-1][0][0];
00079 }
00080 }
00081
00082
00083
00084 }
00085
00086 double Model_train::friction_ = 0.25;
00087
00088 Model_train::Model_train(Model_track* t, char sect, double inert, double pos)
00089 : track_(t),
00090 sector_(sect),
00091 inertia_(inert),
00092 pos_in_track_(pos),
00093 speed_(0.0),
00094 actual_speed_(0.0)
00095 { }
00096
00097 void Model_train::tick()
00098 {
00099 double sign;
00100 if ( sector_ == 0 ) return;
00101
00102 if ( speed_ >= 0.0 ) {
00103 sign = 1.0;
00104 } else {
00105 sign = -1.0;
00106 }
00107
00108 track_->position(actual_speed_, pos_in_track_, sector_);
00109
00110 if ( fabs(speed_) - fabs(actual_speed_) > 1e-6 ) {
00111 actual_speed_ += sign*inertia_;
00112 if ( fabs(speed_) < fabs(actual_speed_) )
00113 actual_speed_ = speed_;
00114
00115 } else if(fabs(speed_) - fabs(actual_speed_) < 1e-6) {
00116 actual_speed_ -= sign*(inertia_+friction_);
00117 if (fabs(speed_) > fabs(actual_speed_))
00118 actual_speed_ = speed_;
00119
00120 } else {
00121 actual_speed_ = speed_;
00122 }
00123 }
00124
00125
00126 Fake_controller::Fake_controller()
00127 : track_(),
00128
00129 train1_(&track_, 3, 0.0),
00130 train2_(&track_, 5, 0.0),
00131 train4_(&track_, 12,0.0)
00132 {
00133 train1_.set_speed(0);
00134 train2_.set_speed(0);
00135 train4_.set_speed(0);
00136 }
00137
00138 USHORT Fake_controller::get_position_mask()
00139 {
00140 USHORT posmask = 0;
00141 posmask |= (1 << (train1_.get_pos()-1));
00142 posmask |= (1 << (train2_.get_pos()-1));
00143 posmask |= (1 << (train4_.get_pos()-1));
00144 return posmask;
00145 }
00146
00147 BOOL Fake_controller::set_train_speed(int num, SCHAR spd)
00148 {
00149 switch(num) {
00150 case 1:
00151 train1_.set_speed(spd);
00152 return TRUE;
00153 case 2:
00154 train2_.set_speed(spd);
00155 return TRUE;
00156 case 4:
00157 train2_.set_speed(spd);
00158 return TRUE;
00159 }
00160 return FALSE;
00161 }
00162
00163 BOOL Fake_controller::set_switch(int num, switchpoint_t pos)
00164 {
00165 if ( num < 0 || num > 3 ) return FALSE;
00166
00167 track_.switch_point(num, pos);
00168 return TRUE;
00169 }
00170
00171 void Fake_controller::tick()
00172 {
00173 train1_.tick();
00174 train2_.tick();
00175 train4_.tick();
00176 }
00177
00178 char Fake_controller::next_position(char current_pos, SCHAR direction)
00179 {
00180 char tpos = current_pos;
00181 double fine;
00182
00183
00184 if (direction > 0) {
00185 fine = 1.0;
00186 } else {
00187 fine = 0.0;
00188 }
00189
00190 track_.position(direction, fine, tpos);
00191 return tpos;
00192 }
00193
00194 #include "marshal.hh"
00195 #include <time.h>
00196
00197 BEGIN_MESSAGE_TABLE(Fake_controller)
00198 MESSAGE(unmarshal_none_rushort, &Fake_controller::get_position_mask)
00199 MESSAGE(unmarshal_int_schar_rbool, &Fake_controller::set_train_speed )
00200 MESSAGE(unmarshal_int_swpointt_rbool, &Fake_controller::set_switch )
00201 END_MESSAGE_TABLE;
00202
00203 #define MSG_get_position_mask 0
00204 #define MSG_set_train_speed 1
00205 #define MSG_set_switch 2
00206
00207 Fake_controller_proxy::Fake_controller_proxy(int msec, int alg, int prio)
00208 {
00209 timespec ts;
00210 ts.tv_sec = msec/1000;
00211 ts.tv_usec = (msec%1000) * 1000;
00212 ctrl_.start(ts, alg, prio);
00213 }
00214
00215 Fake_controller_proxy::~Fake_controller_proxy()
00216 {
00217 ctrl_.stop();
00218 }
00219
00220 USHORT Fake_controller_proxy::get_position_mask()
00221 {
00222 return marshal_none_rushort(&ctrl_, MSG_get_position_mask);
00223 }
00224
00225 BOOL Fake_controller_proxy::set_train_speed(int num, SCHAR spd)
00226 {
00227 return marshal_int_schar_rbool(&ctrl_, MSG_set_train_speed, num, spd);
00228 }
00229
00230 BOOL Fake_controller_proxy::set_switch(int num, switchpoint_t pos)
00231 {
00232 return marshal_int_swpointt_rbool(&ctrl_, MSG_set_switch, num, pos);
00233 }
00234
00235 #endif