00001 #include "Controller.h"
00002 #include "Motion/EmergencyStopMC.h"
00003 #include "Motion/LedMC.h"
00004 #include "Motion/MMAccessor.h"
00005 #include "Shared/SharedObject.h"
00006 #include "Shared/WorldState.h"
00007 #include "Shared/get_time.h"
00008 #include "SoundPlay/SoundManager.h"
00009 #include "Events/TextMsgEvent.h"
00010 #include "Shared/ERS210Info.h"
00011 #include "Shared/ERS220Info.h"
00012 #include "Shared/DynamicConfig.h"
00013 #include "Shared/string_util.h"
00014 #include <sstream>
00015
00016 Controller * Controller::theOneController=NULL;
00017
00018
00019 EventBase Controller::nextItem;
00020 EventBase Controller::prevItem;
00021 EventBase Controller::nextItemFast;
00022 EventBase Controller::prevItemFast;
00023 EventBase Controller::selectItem;
00024 EventBase Controller::cancel;
00025
00026 using namespace string_util;
00027
00028
00029 void Controller::DoStart() {
00030 BehaviorBase::DoStart();
00031 sndman->LoadFile(config->controller.select_snd);
00032 sndman->LoadFile(config->controller.next_snd);
00033 sndman->LoadFile(config->controller.prev_snd);
00034 sndman->LoadFile(config->controller.read_snd);
00035 sndman->LoadFile(config->controller.cancel_snd);
00036 erouter->addListener(this,EventBase::estopEGID);
00037
00038 wireless->setReceiver(gui_comm->sock, gui_comm_callback);
00039 wireless->listen(gui_comm->sock, config->controller.gui_port);
00040 theOneController=this;
00041 reset();
00042 }
00043
00044 void Controller::DoStop() {
00045 sndman->ReleaseFile(config->controller.select_snd);
00046 sndman->ReleaseFile(config->controller.next_snd);
00047 sndman->ReleaseFile(config->controller.prev_snd);
00048 sndman->ReleaseFile(config->controller.read_snd);
00049 sndman->ReleaseFile(config->controller.cancel_snd);
00050 erouter->forgetListener(this);
00051 reset();
00052 wireless->close(gui_comm);
00053 theOneController=NULL;
00054 BehaviorBase::DoStop();
00055 }
00056
00057 bool Controller::trapEvent(const EventBase& e) {
00058 if(!chkCmdStack())
00059 return false;
00060 last_time=cur_time;
00061 cur_time=get_time();
00062 if(nextItem.sameGenSource(e)) {
00063 nextEv_val=e.getMagnitude();
00064 nextEv_dur=e.getDuration();
00065 if(nextEv_val==0 && prevEv_val==0)
00066 alreadyGotBoth=false;
00067 if(nextEv_val>.75 && prevEv_val>.75 && nextEv_dur<666 && prevEv_dur<666)
00068 if(alreadyGotBoth)
00069 return true;
00070 else {
00071 alreadyGotBoth=true;
00072 return setNext(cmdstack.top()->doReadStdIn());
00073 }
00074 if(e.getTypeID()==nextItem.getTypeID() && e.getDuration()<666)
00075 return setNext(cmdstack.top()->doNextItem());
00076 if(e.getTypeID()==nextItemFast.getTypeID() && e.getDuration()>666 && calcPulse(cur_time,last_time,static_cast<unsigned int>(50/e.getMagnitude())))
00077 return setNext(cmdstack.top()->doNextItem());
00078 }
00079 if(prevItem.sameGenSource(e)) {
00080 prevEv_val=e.getMagnitude();
00081 prevEv_dur=e.getDuration();
00082 if(nextEv_val==0 && prevEv_val==0)
00083 alreadyGotBoth=false;
00084 if(nextEv_val>.75 && prevEv_val>.75 && nextEv_dur<666 && prevEv_dur<666)
00085 if(alreadyGotBoth)
00086 return true;
00087 else {
00088 alreadyGotBoth=true;
00089 return setNext(cmdstack.top()->doReadStdIn());
00090 }
00091 if(e.getTypeID()==prevItem.getTypeID() && e.getDuration()<666)
00092 return setNext(cmdstack.top()->doPrevItem());
00093 if(e.getTypeID()==prevItemFast.getTypeID() && e.getDuration()>666 && calcPulse(cur_time,last_time,static_cast<unsigned int>(50/e.getMagnitude())))
00094 return setNext(cmdstack.top()->doPrevItem());
00095 }
00096 if(e.getDuration()>250) {
00097 if(e==selectItem)
00098 return setNext(cmdstack.top()->doSelect());
00099 if(e==cancel)
00100 return setNext(cmdstack.top()->doCancel());
00101 }
00102 return true;
00103 }
00104
00105 void Controller::processEvent(const EventBase& event) {
00106 if(event.getTypeID()==EventBase::activateETID) {
00107 if(display==MotionManager::invalid_MC_ID)
00108 activate();
00109 } else {
00110 if(display!=MotionManager::invalid_MC_ID)
00111 deactivate();
00112 }
00113 }
00114
00115 void Controller::reset() {
00116 while(cmdstack.size()>1)
00117 pop();
00118 if(!cmdstack.empty()) {
00119 cmdstack.top()->deactivate();
00120 cmdstack.pop();
00121 }
00122 refresh();
00123 }
00124
00125 void Controller::refresh() {
00126 if(!chkCmdStack())
00127 return;
00128 cmdstack.top()->refresh();
00129 }
00130
00131 void Controller::push(ControlBase* c) {
00132 if(!chkCmdStack())
00133 return;
00134 cmdstack.top()->pause();
00135 cmdstack.push(c);
00136 theOneController->gui_comm->printf("push\n");
00137 setNext(cmdstack.top()->activate(display,gui_comm));
00138 }
00139
00140 void Controller::pop() {
00141 cmdstack.top()->deactivate();
00142 cmdstack.pop();
00143 theOneController->gui_comm->printf("pop\n");
00144 refresh();
00145 }
00146
00147 Controller& Controller::setRoot(ControlBase* r) {
00148 reset();
00149 root=r;
00150 refresh();
00151 return *this;
00152 }
00153
00154 Controller& Controller::setEStopID(MotionManager::MC_ID estopid) {
00155 estop_id=estopid;
00156 if(static_cast<EmergencyStopMC*>(motman->peekMotion(estopid))->getStopped()) {
00157 if(display==MotionManager::invalid_MC_ID)
00158 activate();
00159 } else {
00160 if(display!=MotionManager::invalid_MC_ID)
00161 deactivate();
00162 }
00163 return *this;
00164 }
00165
00166 void Controller::loadGUI(const std::string& type, const std::string& name, unsigned int port, const std::vector<std::string>& args) {
00167 std::stringstream ss;
00168 ss << "load\n" << type << '\n' << name << '\n' << port << '\n';
00169 for(unsigned int i=0; i<args.size(); i++) {
00170 ss << '"';
00171 for(unsigned int j=0; j<args[i].size(); j++) {
00172 if(args[i][j]=='\\' || args[i][j]=='"' || args[i][j]=='\n')
00173 ss << '\\';
00174 ss << args[i][j];
00175 }
00176 ss << "\" ";
00177 }
00178 ss << '\n';
00179 theOneController->gui_comm->write((const byte*)ss.str().c_str(),ss.str().size());
00180 }
00181
00182 void Controller::closeGUI(const std::string& name) {
00183 ASSERTRET(theOneController!=NULL,"null controller");
00184 ASSERTRET(theOneController->gui_comm!=NULL,"null gui_comm");
00185
00186 theOneController->gui_comm->printf("close\n%s\n",name.c_str());
00187 }
00188
00189 int Controller::gui_comm_callback(char *buf, int bytes) {
00190 std::string s(buf,bytes);
00191
00192 if(theOneController==NULL)
00193 return 0;
00194
00195 static std::string incomplete;
00196
00197
00198 while(s.size()>0) {
00199 unsigned int endline=s.find('\n');
00200 if(endline==std::string::npos) {
00201 incomplete+=s;
00202 return 0;
00203 }
00204 incomplete+=s.substr(0,endline);
00205 theOneController->takeLine(incomplete);
00206 incomplete.erase();
00207 s=s.substr(endline+1);
00208 }
00209
00210 return 0;
00211 }
00212
00213 int Controller::console_callback(char *buf, int bytes) {
00214 std::string s(buf,bytes);
00215
00216 if(theOneController==NULL)
00217 return 0;
00218
00219 static std::string incomplete;
00220
00221
00222 while(s.size()>0) {
00223 unsigned int endline=s.find('\n');
00224 if(endline==std::string::npos) {
00225 incomplete+=s;
00226 return 0;
00227 }
00228 incomplete+=s.substr(0,endline);
00229
00230 if(wireless->isConnected(theOneController->gui_comm->sock))
00231 erouter->postEvent(new TextMsgEvent(incomplete));
00232 else
00233 theOneController->takeLine(incomplete);
00234 incomplete.erase();
00235 s=s.substr(endline+1);
00236 }
00237
00238 return 0;
00239 }
00240
00241 void Controller::init() {
00242 wireless->setDaemon(gui_comm);
00243 if(state->robotDesign & WorldState::ERS210Mask) {
00244 nextItem=EventBase(EventBase::buttonEGID,ERS210Info::HeadFrButOffset,EventBase::deactivateETID,0);
00245 prevItem=EventBase(EventBase::buttonEGID,ERS210Info::HeadBkButOffset,EventBase::deactivateETID,0);
00246 nextItemFast=EventBase(EventBase::buttonEGID,ERS210Info::HeadFrButOffset,EventBase::statusETID,666);
00247 prevItemFast=EventBase(EventBase::buttonEGID,ERS210Info::HeadBkButOffset,EventBase::statusETID,666);
00248 selectItem=EventBase(EventBase::buttonEGID,ERS210Info::ChinButOffset,EventBase::deactivateETID,250);
00249 cancel=EventBase(EventBase::buttonEGID,ERS210Info::BackButOffset,EventBase::deactivateETID,250);
00250 } else if(state->robotDesign & WorldState::ERS220Mask) {
00251 nextItem=EventBase(EventBase::buttonEGID,ERS220Info::TailLeftButOffset,EventBase::deactivateETID,0);
00252 prevItem=EventBase(EventBase::buttonEGID,ERS220Info::TailRightButOffset,EventBase::deactivateETID,0);
00253
00254
00255
00256
00257
00258 nextItemFast=EventBase(EventBase::buttonEGID,ERS220Info::TailLeftButOffset,EventBase::statusETID,666);
00259 prevItemFast=EventBase(EventBase::buttonEGID,ERS220Info::TailRightButOffset,EventBase::statusETID,666);
00260 selectItem=EventBase(EventBase::buttonEGID,ERS220Info::TailCenterButOffset,EventBase::deactivateETID,50);
00261 cancel=EventBase(EventBase::buttonEGID,ERS220Info::BackButOffset,EventBase::deactivateETID,50);
00262 }
00263 }
00264
00265 void Controller::takeLine(const std::string& s) {
00266
00267 if(s.size()==0)
00268 return;
00269
00270 std::vector<std::string> args;
00271 std::vector<unsigned int> offsets;
00272 if(!string_util::parseArgs(s,args,offsets)) {
00273 serr->printf("Controller::takeLine(\"%s\") was malformed.\n",s.c_str());
00274 return;
00275 }
00276
00277 unsigned int last=offsets[0];
00278 for(unsigned int i=0; i<args.size(); i++) {
00279 if(args[i]==";") {
00280 takeLine(s.substr(last,offsets[i]-last));
00281 if(i+1==args.size())
00282 return;
00283 last=offsets[i+1];
00284 }
00285 if(args[i]=="\\;")
00286 args[i]=";";
00287 }
00288 if(!chkCmdStack())
00289 return;
00290 if(args[0][0]!='!') {
00291 setNext(cmdstack.top()->takeInput(s));
00292 } else {
00293 if(last!=offsets[0]) {
00294 takeLine(s.substr(last));
00295 } else if(args[0]=="!refresh") {
00296 refresh();
00297 } else if(args[0]=="!reset") {
00298 reset();
00299 } else if(args[0]=="!cancel") {
00300 setNext(cmdstack.top()->doCancel());
00301 } else if(args[0]=="!select") {
00302 setNext(cmdstack.top()->doSelect());
00303 } else if(args[0]=="!next") {
00304 setNext(cmdstack.top()->doNextItem());
00305 } else if(args[0]=="!prev") {
00306 setNext(cmdstack.top()->doPrevItem());
00307 } else if(args[0]=="!msg") {
00308 erouter->postEvent(new TextMsgEvent(s.substr(offsets[1])));
00309 } else if(args[0]=="!hello") {
00310 static unsigned int count=0;
00311 count++;
00312 theOneController->gui_comm->printf("hello\n%d\n",count);
00313 } else if(args[0]=="!root") {
00314 ControlBase * ret=root->takeInput(s.substr(offsets[1]));
00315 if(ret!=NULL)
00316 setNext(ret);
00317 } else if(args[0]=="!hilight") {
00318 std::vector<unsigned int> hilights;
00319 for(unsigned int i=1; i<args.size(); i++)
00320 hilights.push_back(atoi(args[i].c_str()));
00321 cmdstack.top()->setHilights(hilights);
00322 } else if(args[0]=="!input") {
00323 const std::vector<unsigned int>& hilights=cmdstack.top()->getHilights();
00324 const std::vector<ControlBase*>& slots=cmdstack.top()->getSlots();
00325 std::string in=s.substr(offsets[1]);
00326 for(unsigned int i=0; i<hilights.size(); i++)
00327 if(hilights[i]<slots.size() && slots[hilights[i]]!=NULL) {
00328 ControlBase * ret=slots[hilights[i]]->takeInput(in);
00329 if(ret!=NULL)
00330 setNext(ret);
00331 }
00332 refresh();
00333 } else if(args[0]=="!set") {
00334 DynamicConfig::assignVarFromController(s.substr(offsets[1]).c_str());
00335 } else
00336 setNext(cmdstack.top()->takeInput(s));
00337 }
00338 }
00339
00340 bool Controller::setNext(ControlBase* next) {
00341 if(next==NULL)
00342 pop();
00343 else if(next!=cmdstack.top())
00344 push(next);
00345 return true;
00346 }
00347
00348 void Controller::activate() {
00349 SharedObject<LedMC> leds;
00350 leds->setWeights(~FaceLEDMask,0);
00351 leds->setWeights(FaceLEDMask,.75);
00352 display=motman->addMotion(leds,MotionManager::kEmergencyPriority);
00353 erouter->addTrapper(this,EventBase::buttonEGID);
00354 if(!cmdstack.empty())
00355 cmdstack.top()->activate(display,gui_comm);
00356 else
00357 chkCmdStack();
00358 }
00359
00360 void Controller::deactivate() {
00361 motman->removeMotion(display);
00362
00363 for(unsigned int i=LEDOffset; i<LEDOffset+NumLEDs; i++)
00364 motman->setOutput(NULL,i,0.f);
00365 display=MotionManager::invalid_MC_ID;
00366 erouter->removeTrapper(this);
00367 cmdstack.top()->pause();
00368 }
00369
00370 bool Controller::chkCmdStack() {
00371 if(cmdstack.empty()) {
00372 if(root==NULL)
00373 return false;
00374 cmdstack.push(root);
00375 ControlBase * next = cmdstack.top()->activate(display,gui_comm);
00376 if(next==NULL)
00377 cout << "*** WARNING Controller root returned NULL on activate!" << endl;
00378 else if(next!=root)
00379 push(next);
00380 }
00381 return true;
00382 }
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394