00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "property.hh"
00025 #include "extrapolatedproperty.hh"
00026
00027 set<ExtrapolatedProperty*> ExtrapolatedProperty::allexps;
00028
00029
00030 ExtrapolatedProperty::ExtrapolatedProperty(MetaObject* superobject)
00031 : MetaObject(superobject), Property(superobject)
00032 {
00033 allexps.insert(this);
00034 }
00035
00036 ExtrapolatedProperty::~ExtrapolatedProperty()
00037 {
00038 allexps.erase(this);
00039 }
00040
00041 void ExtrapolatedProperty::registerExtenders()
00042 {
00043 static bool done = false;
00044 if(! done) {
00045 LocalSite::addLocalObjectExtension("property:property.extrapolated", ExtrapolatedLocalProperty::new_ExtrapolatedLocalProperty);
00046 LocalSite::addLocalObjectExtension(typeid(ExtrapolatedLocalProperty).name(), ExtrapolatedLocalProperty::new_ExtrapolatedLocalProperty);
00047 LocalSite::addLocalObjectExtension(typeid(ExtrapolatedProperty).name(), ExtrapolatedLocalProperty::new_ExtrapolatedLocalProperty);
00048 RemoteSite::addRemoteObjectExtension("property:property.extrapolated", ExtrapolatedRemoteProperty::new_ExtrapolatedRemoteProperty);
00049 RemoteSite::addRemoteObjectExtension(typeid(ExtrapolatedRemoteProperty).name(), ExtrapolatedRemoteProperty::new_ExtrapolatedRemoteProperty);
00050 RemoteSite::addRemoteObjectExtension(typeid(ExtrapolatedProperty).name(), ExtrapolatedRemoteProperty::new_ExtrapolatedRemoteProperty);
00051 done = true;
00052 }
00053 }
00054
00055 string ExtrapolatedProperty::stringifyVector(const vector<double>& x)
00056 {
00057 string out;
00058 char n[64];
00059
00060 if(x.size() > 0) {
00061 snprintf(n, sizeof(n), "%f", x[0]);
00062 out += n;
00063 for(unsigned int i = 1; i < x.size(); i++) {
00064 out += " ";
00065 snprintf(n, sizeof(n), "%f", x[i]);
00066 out += n;
00067 }
00068 }
00069
00070 return out;
00071 }
00072
00073 void ExtrapolatedProperty::updateAll()
00074 {
00075 for(AllExpSet::iterator i = allexps.begin(); i != allexps.end(); i++) {
00076 try {
00077 (*i)->update();
00078 } catch(runtime_error e) {
00079 LOG("extrapolatedproperty", 2, "updateAll caught exception: " << e.what());
00080 }
00081 }
00082 }
00083
00084 void ExtrapolatedProperty::calculatePosition(vector<double>& newx, vector<double>& newdx, double& t)
00085 {
00086 t = now() - lastCheckpoint;
00087
00088
00089
00090
00091 newx.resize(x.size());
00092 newdx.resize(x.size());
00093
00094 for(unsigned int i = 0; i < x.size(); i++) {
00095 newx[i] = (ddx[i]/2)*(t*t) + dx[i]*t + x[i];
00096 newdx[i] = ddx[i]*t + dx[i];
00097 }
00098 }
00099
00100 bool isVectorZero (vector<double> v)
00101 {
00102 for (unsigned int i = 0; i < v.size(); i++)
00103 if (v[i] != 0) return false;
00104 return true;
00105 }
00106
00107 void ExtrapolatedProperty::update()
00108 {
00109 if (isVectorZero (dx) && isVectorZero (ddx)) return;
00110
00111 vector<double> newx;
00112 vector<double> newdx;
00113 double t;
00114
00115 calculatePosition(newx, newdx, t);
00116
00117
00118
00119 Property::replace(stringifyVector(newx), "text/x-vector-float");
00120
00121 for(ExtrapolationListenerSet::iterator i = extrapolationListeners.begin();
00122 i != extrapolationListeners.end();
00123 i++)
00124 {
00125 (*i)->notifyPositionChange(*this, newx, newdx, ddx, t);
00126 }
00127 }
00128
00129 void ExtrapolatedProperty::addExtrapolationListener(ExtrapolatedPropertyListener* el)
00130 {
00131 extrapolationListeners.insert(el);
00132 if(RefCounted* rc = dynamic_cast<RefCounted*>(el)) {
00133 rc->acquire();
00134 rc->addExciseListener(this);
00135 }
00136
00137 double t = now() - lastCheckpoint;
00138 el->notifyBaseChange(*this, x, dx, ddx, t);
00139 vector<double> newx;
00140 vector<double> newdx;
00141 calculatePosition(newx, newdx, t);
00142 el->notifyPositionChange(*this, newx, newdx, ddx, t);
00143 }
00144
00145 void ExtrapolatedProperty::removeExtrapolationListener(ExtrapolatedPropertyListener* x)
00146 {
00147 extrapolationListeners.erase(x);
00148 if(RefCounted* rc = dynamic_cast<RefCounted*>(x)) {
00149 rc->removeExciseListener(this);
00150 rc->release();
00151 }
00152 }
00153
00154 void ExtrapolatedProperty::notifyObjectExcise(RefCounted* object)
00155 {
00156 Property::notifyObjectExcise(object);
00157
00158 if(ExtrapolatedPropertyListener* pl = dynamic_cast<ExtrapolatedPropertyListener*>(object)) {
00159 removeExtrapolationListener(pl);
00160 }
00161 }
00162
00163 void ExtrapolatedProperty::doExcise()
00164 {
00165 Property::doExcise();
00166
00167 for(ExtrapolationListenerSet::iterator i = extrapolationListeners.begin();
00168 i != extrapolationListeners.end(); i++)
00169 {
00170 if(RefCounted* rc = dynamic_cast<RefCounted*>(*i)) {
00171 rc->removeExciseListener(this);
00172 rc->release();
00173 }
00174 }
00175 extrapolationListeners.clear();
00176 }
00177
00178 void ExtrapolatedProperty::stringToVector(const string& prop, vector<double>& x)
00179 {
00180 unsigned int i = 0;
00181 double value;
00182
00183 x.clear();
00184 while(i < prop.size()) {
00185 while(i < prop.size() && isspace(prop[i])) i++;
00186 if(i >= prop.size()) break;
00187 if(sscanf(prop.c_str() + i, "%lf", &value) != 1) break;
00188 x.push_back(value);
00189 while(i < prop.size() && !isspace(prop[i])) i++;
00190 }
00191 }
00192
00193 const string ExtrapolatedProperty::getType()
00194 {
00195 return "property:property.extrapolated";
00196 }
00197
00198 double ExtrapolatedProperty::now()
00199 {
00200 #ifdef WIN32
00201 return getTimer();
00202 #else
00203 return getRealTime();
00204 #endif
00205 }
00206
00207 void ExtrapolatedProperty::getCurrent(vector<double>& ax,
00208 vector<double>& adx,
00209 vector<double>& addx,
00210 double& t)
00211 {
00212 calculatePosition(ax, adx, t);
00213 if(ddx.size() != x.size()) ddx.resize(x.size());
00214 addx = ddx;
00215
00216 t = now() - lastCheckpoint;
00217 }
00218
00219 void ExtrapolatedProperty::getBase(vector<double>& ax,
00220 vector<double>& adx,
00221 vector<double>& addx)
00222 {
00223 ax = x;
00224 adx = dx;
00225 addx = ddx;
00226 }
00227
00228 void ExtrapolatedProperty::read(string& target, int start, int length) {
00229 readRaw(target, start, length);
00230 }
00231
00232 int ExtrapolatedProperty::getLength() {
00233 return getRawLength();
00234 }
00235
00236
00237 void ExtrapolatedProperty::readRaw(string& target, int start, int length) {
00238 vector<double> newx;
00239 vector<double> newdx;
00240 double t;
00241
00242 calculatePosition(newx, newdx, t);
00243 if(length == -1)
00244 target = stringifyVector(newx).substr(start);
00245 else
00246 target = stringifyVector(newx).substr(start, length);
00247
00248 }
00249
00250 int ExtrapolatedProperty::getRawLength() {
00251 vector<double> newx;
00252 vector<double> newdx;
00253 double t;
00254
00255 calculatePosition(newx, newdx, t);
00256
00257 return stringifyVector(newx).size();
00258 }
00259
00260
00261
00262
00263
00264 ExtrapolatedLocalProperty::ExtrapolatedLocalProperty(MetaObject* superobject)
00265 : MetaObject(superobject), Property(superobject), LocalProperty(superobject),
00266 BufferedLocalProperty(superobject), ExtrapolatedProperty(superobject),
00267 extrap_base_changed(true)
00268 {
00269 }
00270
00271 ExtrapolatedLocalProperty::~ExtrapolatedLocalProperty()
00272 {
00273 }
00274
00275 MetaObject* ExtrapolatedLocalProperty::new_ExtrapolatedLocalProperty(MetaObject* superobject, const string& type)
00276 {
00277 return new ExtrapolatedLocalProperty(superobject);
00278 }
00279
00280 void ExtrapolatedLocalProperty::write(int start, const string& newdata)
00281 {
00282 readRaw(raw_data, 0, -1);
00283 raw_data.replace(start, newdata.size(), newdata);
00284 stringToVector(raw_data, x);
00285 BufferedLocalProperty::replace(raw_data, getDataType());
00286 dx.clear();
00287 ddx.clear();
00288 for(unsigned int i = 0; i < x.size(); i++) {
00289 dx.push_back(0);
00290 ddx.push_back(0);
00291 }
00292 extrap_base_changed = true;
00293 }
00294
00295 void ExtrapolatedLocalProperty::replace(const string& newdata, const string& newtype)
00296 {
00297 vector<double> newx;
00298 stringToVector(newdata, newx);
00299 dx.clear();
00300 ddx.clear();
00301 for(unsigned int i = 0; i < x.size(); i++) {
00302 dx.push_back(0);
00303 ddx.push_back(0);
00304 }
00305 BufferedLocalProperty::replace(newdata, newtype);
00306 setPosition(newx);
00307 }
00308
00309 void ExtrapolatedLocalProperty::set(const vector<double>& ax,
00310 const vector<double>& adx,
00311 const vector<double>& addx,
00312 double t)
00313 {
00314 x.resize(ax.size());
00315 x = ax;
00316 dx = adx;
00317 ddx = addx;
00318 dx.resize(x.size());
00319 ddx.resize(x.size());
00320
00321 lastCheckpoint = now() - t;
00322
00323 extrap_base_changed = true;
00324
00325 for(ExtrapolationListenerSet::iterator i = extrapolationListeners.begin();
00326 i != extrapolationListeners.end();
00327 i++)
00328 {
00329 try {
00330
00331 if(! dynamic_cast<ExtrapolatedListenerSiteWrapper*>(*i)) (*i)->notifyBaseChange(*this, x, dx, ddx, t);
00332 } catch(...) { }
00333 }
00334 }
00335
00336 void ExtrapolatedLocalProperty::sendMessage(Message* m)
00337 {
00338
00339 BufferedLocalProperty::sendMessage(m);
00340
00341 rREF(Vobject&, from, findObjectFromRoot(m->getFrom()),
00342
00343 if(m->getMethod() == "property:start-listening") {
00344 try {
00345 for(int i = 0; i < m->getNumFields(); i++) {
00346 if(m->getField(i).key == "listen"
00347 && m->getField(i).value == "property.extrapolated") {
00348 vRef<Site> st = m->getSourceSite();
00349
00350 vRef<PropertyEvent> event = new PropertyEvent(
00351 PropertyEvent::PropertyRead,
00352 from, *this,
00353 BufferedLocalProperty::read(),
00354 getDataType(),
00355 true);
00356 string message;
00357 if(validatePropertyAccess(*event, message)) {
00358 ExtrapolatedPropertyListener* pl = new ExtrapolatedListenerSiteWrapper(&st);
00359 addExtrapolationListener(pl);
00360 st->addExciseListener(this);
00361 try {
00362 pl->notifyBaseChange(*this, x, dx, ddx, now() - lastCheckpoint);
00363 } catch(...) { }
00364 }
00365 break;
00366 }
00367 }
00368 } catch(Message::NoSuchFieldError) { }
00369 } else if(m->getMethod() == "property:extrapolated-set") {
00370 string nx;
00371 string ndx;
00372 string nddx;
00373
00374 try {
00375 nx = m->getField("x").value;
00376 } catch(Message::NoSuchFieldError) { }
00377 try {
00378 ndx = m->getField("dx").value;
00379 } catch(Message::NoSuchFieldError) { }
00380 try {
00381 nddx = m->getField("ddx").value;
00382 } catch(Message::NoSuchFieldError) {
00383 }
00384 pREF(Message*, reply, new Message(),
00385 LocalVobject::initReply(this, reply, m, "property:extrapolated-update");
00386 string dt = getDataType();
00387
00388 vRef<PropertyEvent> event = new PropertyEvent(
00389 PropertyEvent::PropertyReplace,
00390 from, *this,
00391 nx, dt,
00392 BufferedLocalProperty::read(),
00393 dt,
00394 true);
00395 string message;
00396 if(validatePropertyAccess(*event, message)) {
00397 vector<double> _x;
00398 vector<double> _dx;
00399 vector<double> _ddx;
00400
00401 stringToVector(nx, _x);
00402 stringToVector(ndx, _dx);
00403 stringToVector(nddx, _ddx);
00404
00405 set(_x, _dx, _ddx);
00406
00407 nx = stringifyVector(x);
00408 ndx = stringifyVector(dx);
00409 nddx = stringifyVector(ddx);
00410 ndx.resize(nx.size());
00411 nddx.resize(nx.size());
00412
00413 double t = now() - lastCheckpoint;
00414 char st[32];
00415 snprintf(st, sizeof(st), "%f", t);
00416
00417 reply->insertField(-1, "x", nx);
00418 reply->insertField(-1, "dx", ndx);
00419 reply->insertField(-1, "ddx", nddx);
00420 reply->insertField(-1, "t", st);
00421 } else {
00422 reply->insertField(-1, "error", message);
00423 }
00424 from.sendMessage(reply);
00425 );
00426 }
00427 );
00428 }
00429
00430 void ExtrapolatedLocalProperty::flush()
00431 {
00432 changed = true;
00433 BufferedLocalProperty::flush();
00434 if(extrap_base_changed) {
00435 double t = now() - lastCheckpoint;
00436 for(ExtrapolationListenerSet::iterator i = extrapolationListeners.begin();
00437 i != extrapolationListeners.end();
00438 i++)
00439 {
00440
00441 try {
00442 if(dynamic_cast<ExtrapolatedListenerSiteWrapper*>(*i)) (*i)->notifyBaseChange(*this, x, dx, ddx, t);
00443 } catch(...) { }
00444 }
00445 extrap_base_changed = false;
00446 }
00447 }
00448
00449
00450
00451
00452
00453 ExtrapolatedRemoteProperty::~ExtrapolatedRemoteProperty()
00454 {
00455 }
00456
00457 ExtrapolatedRemoteProperty::ExtrapolatedRemoteProperty(MetaObject* superobject)
00458 : MetaObject(superobject), Property(superobject), RemoteProperty(superobject),
00459 BufferedRemoteProperty(superobject), ExtrapolatedProperty(superobject)
00460 {
00461 }
00462
00463 MetaObject* ExtrapolatedRemoteProperty::new_ExtrapolatedRemoteProperty(MetaObject* superobject, const string& type)
00464 {
00465 return new ExtrapolatedRemoteProperty(superobject);
00466 }
00467
00468 void ExtrapolatedRemoteProperty::addExtrapolationListener(ExtrapolatedPropertyListener* x)
00469 {
00470 if(extrapolationListeners.empty()) {
00471 pREF(Message*, m, new Message(),
00472 rREF(LocalSite&, ls, RemoteVobject::initFields(this, m, "property:start-listening", false), );
00473 m->insertField(-1, "listen", "property.extrapolated");
00474
00475 sendMessage(m);
00476 );
00477 }
00478 ExtrapolatedProperty::addExtrapolationListener(x);
00479 }
00480
00481 void ExtrapolatedRemoteProperty::removeExtrapolationListener(ExtrapolatedPropertyListener* x)
00482 {
00483 ExtrapolatedProperty::removeExtrapolationListener(x);
00484 if(extrapolationListeners.empty()) {
00485 pREF(Message*, m, new Message(),
00486 rREF(LocalSite&, ls, RemoteVobject::initFields(this, m, "property:stop-listening", false), );
00487 m->insertField(-1, "listen", "property.extrapolated");
00488
00489 sendMessage(m);
00490 );
00491 }
00492 }
00493
00494 void ExtrapolatedRemoteProperty::set(const vector<double>& x, const vector<double>& dx, const vector<double>& ddx, double t)
00495 {
00496 pREF(Message*, m, new Message(),
00497 rREF(LocalSite&, ls, RemoteVobject::initFields(this, m, "property:extrapolated-set", false), );
00498
00499 char st[32];
00500 snprintf(st, sizeof(st), "%f", t);
00501
00502 m->insertField(-1, "x", stringifyVector(x));
00503 m->insertField(-1, "dx", stringifyVector(dx));
00504 m->insertField(-1, "ddx", stringifyVector(ddx));
00505 m->insertField(-1, "t", st);
00506
00507 sendMessage(m);
00508 );
00509 }
00510
00511 void ExtrapolatedRemoteProperty::sendUpdateMessage(Message* m)
00512 {
00513 BufferedRemoteProperty::sendMessage(m);
00514
00515 if(m->getMethod() == "property:extrapolated-update") {
00516 LOG("extrapolatedproperty", 3, "got extrap: " << m->getLoggableString());
00517 try {
00518 const Message::Field& _st = m->getField("t");
00519 const Message::Field& _sx = m->getField("x");
00520 const Message::Field& _sdx = m->getField("dx");
00521 const Message::Field& _sddx = m->getField("ddx");
00522
00523 double _t;
00524
00525 stringToVector(_sx.value, x);
00526 stringToVector(_sdx.value, dx);
00527 stringToVector(_sddx.value, ddx);
00528
00529 sscanf(_st.value.c_str(), "%lf", &_t);
00530
00531 lastCheckpoint = now() - _t;
00532
00533 for(ExtrapolationListenerSet::iterator i = extrapolationListeners.begin();
00534 i != extrapolationListeners.end();
00535 i++)
00536 {
00537 try {
00538 (*i)->notifyBaseChange(*this, x, dx, ddx, _t);
00539 } catch(...) { }
00540 }
00541 } catch(Message::NoSuchFieldError) {
00542 }
00543 }
00544 }
00545
00546
00547
00548 ExtrapolatedListenerSiteWrapper::ExtrapolatedListenerSiteWrapper(Site* s)
00549 : site(s)
00550 {
00551 }
00552
00553 ExtrapolatedListenerSiteWrapper::~ExtrapolatedListenerSiteWrapper()
00554 {
00555 }
00556
00557 void ExtrapolatedListenerSiteWrapper::notifyBaseChange(ExtrapolatedProperty& ep,
00558 const vector<double>& position,
00559 const vector<double>& velocity,
00560 const vector<double>& acceleration,
00561 double t)
00562 {
00563 string nx = ExtrapolatedProperty::stringifyVector(position);
00564 string ndx = ExtrapolatedProperty::stringifyVector(velocity);
00565 string nddx = ExtrapolatedProperty::stringifyVector(acceleration);
00566
00567 char st[32];
00568 snprintf(st, sizeof(st), "%f", t);
00569
00570 vRef<Message> update = new Message();
00571 update->setType("update");
00572 update->setFrom(ep.getURL().getString());
00573 update->setTo(site->getURL().getString());
00574 update->setMethod("property:extrapolated-update");
00575
00576 update->insertField(-1, "x", nx);
00577 update->insertField(-1, "dx", ndx);
00578 update->insertField(-1, "ddx", nddx);
00579 update->insertField(-1, "t", st);
00580
00581 site->sendMessage(&update);
00582 }
00583
00584 void ExtrapolatedListenerSiteWrapper::notifyPositionChange(ExtrapolatedProperty& ep,
00585 const vector<double>& position,
00586 const vector<double>& velocity,
00587 const vector<double>& acceleration,
00588 double t)
00589 {
00590 }
00591
00592
00593
00594
00595 void ExtrapolatedProperty::initialize() {
00596 initialize(1, 0.0);
00597 }
00598
00599 void ExtrapolatedProperty::initialize(unsigned int size, double val) {
00600 vector<double> x;
00601 vector<double> dx;
00602 vector<double> ddx;
00603 x.resize(size);
00604 dx.resize(size);
00605 ddx.resize(size);
00606 for(unsigned int i = 0; i < size; i++)
00607 x[i] = dx[i] = ddx[i] = val;
00608 set(x, dx, ddx, 0);
00609 }
00610
00611 void ExtrapolatedProperty::setVelocity(const vector<double>& newv) {
00612 vector <double>x;
00613 vector <double>v;
00614 vector <double>a;
00615 double t;
00616 getCurrent(x, v, a, t);
00617 x.resize(newv.size());
00618 a.resize(newv.size());
00619 set(x, newv, a, 0);
00620 }
00621
00622 void ExtrapolatedProperty::setAcceleration(const vector<double>& newa) {
00623 vector <double>x;
00624 vector <double>v;
00625 vector <double>a;
00626 double t;
00627 getCurrent(x, v, a, t);
00628 x.resize(newa.size());
00629 v.resize(newa.size());
00630 set(x, v, newa, 0);
00631
00632 }
00633
00634 void ExtrapolatedProperty::setPosition(const vector<double>& newx) {
00635 vector <double>x;
00636 vector <double>v;
00637 vector <double>a;
00638 double t;
00639 getCurrent(x, v, a, t);
00640 v.resize(newx.size());
00641 a.resize(newx.size());
00642 set(newx, v, a, 0);
00643 }
00644
00645 void ExtrapolatedProperty::setVelocity(const double newv) {
00646 vector <double>x;
00647 vector <double>v;
00648 vector <double>a;
00649 double t;
00650 getCurrent(x, v, a, t);
00651 v[0] = newv;
00652 set(x, v, a, 0);
00653 }
00654
00655 void ExtrapolatedProperty::setAcceleration(const double newa) {
00656 vector <double>x;
00657 vector <double>v;
00658 vector <double>a;
00659 double t;
00660 getCurrent(x, v, a, t);
00661 a[0] = newa;
00662 set(x, v, a, 0);
00663 }
00664
00665 void ExtrapolatedProperty::setPosition(const double newx) {
00666 vector <double>x;
00667 vector <double>v;
00668 vector <double>a;
00669 double t;
00670 getCurrent(x, v, a, t);
00671 x[0] = newx;
00672 set(x, v, a, 0);
00673 }
00674
00675
00676
00677 void ExtrapolatedProperty::getCurrentPos(vector<double>& x) {
00678 vector <double>v;
00679 vector <double>a;
00680 double t;
00681 getCurrent(x, v, a, t);
00682 }
00683
00684
00685
00686 void ExtrapolatedProperty::getVelocity(double& val) {
00687 vector <double>x;
00688 vector <double>v;
00689 vector <double>a;
00690 double t;
00691 getCurrent(x, v, a, t);
00692 val = v[0];
00693 }
00694
00695 void ExtrapolatedProperty::getVelocity(vector<double>& v) {
00696 vector <double>x;
00697 vector <double>a;
00698 double t;
00699 getCurrent(x, v, a, t);
00700 }
00701
00702
00703
00704 void ExtrapolatedProperty::getAcceleration(double& acc) {
00705 vector <double>x;
00706 vector <double>v;
00707 vector <double>a;
00708 double t;
00709 getCurrent(x, v, a, t);
00710 acc = a[0];
00711 }
00712
00713 void ExtrapolatedProperty::getAcceleration(vector<double>& a) {
00714 vector <double>x;
00715 vector <double>v;
00716 double t;
00717 getCurrent(x, v, a, t);
00718 }
00719
00720 void ExtrapolatedRemoteProperty::readRaw(string& target, int start, int length) {
00721 if(extrapolationListeners.empty())
00722 RemoteProperty::readRaw(target, start, length);
00723 else
00724 ExtrapolatedProperty::readRaw(target, start, length);
00725 }
00726
00727
00728 int ExtrapolatedRemoteProperty::getRawLength() {
00729 if(extrapolationListeners.empty())
00730 return RemoteProperty::getRawLength();
00731 else
00732 return ExtrapolatedProperty::getRawLength();
00733 }