MoNet.cc

Go to the documentation of this file.
00001 //
00002 // Copyright 2002,2004 Sony Corporation 
00003 //
00004 // Permission to use, copy, modify, and redistribute this software for
00005 // non-commercial use is hereby granted.
00006 //
00007 // This software is provided "as is" without warranty of any kind,
00008 // either expressed or implied, including but not limited to the
00009 // implied warranties of fitness for a particular purpose.
00010 //
00011 
00012 #include <string.h>
00013 #include <OPENR/OPENRAPI.h>
00014 #include <OPENR/OSyslog.h>
00015 #include <OPENR/core_macro.h>
00016 #include <MTNFile.h>
00017 #include "MoNet.h"
00018 
00019 MoNet::MoNet() : moNetState(MNS_IDLE), moNetCommandInfoManager(),
00020                  moNet(), commandArcPath(), 
00021                  currentCommandID(-1), currentPosture(monetpostureNT),
00022                  motionDataID(odesigndataID_UNDEF),
00023                  soundDataID(odesigndataID_UNDEF), motionODA(), soundODA()
00024 {
00025 }
00026 
00027 OStatus
00028 MoNet::DoInit(const OSystemEvent& event)
00029 {
00030     NEW_ALL_SUBJECT_AND_OBSERVER;
00031     REGISTER_ALL_ENTRY;
00032     SET_ALL_READY_AND_NOTIFY_ENTRY;
00033 
00034     LoadMotionODA();
00035     LoadSoundODA();
00036 
00037     char design[orobotdesignNAME_MAX+1];
00038     OStatus result = OPENR::GetRobotDesign(design);
00039     if (result != oSUCCESS) {
00040         OSYSLOG1((osyslogERROR, "%s : %s %d",
00041                   "MoNet::DoInit()",
00042                   "OPENR::GetRobotDesign() FAILED", result));
00043     }
00044 
00045     if (!strcmp(design, "ERS-210") || !strcmp(design, "ERS-220")) {
00046         ReadMoNetConfig(MONET_CONFIG);
00047         ReadMoNetCommandConfig(MONETCMD_CONFIG);
00048     } else if (!strcmp(design, "ERS-7")) {
00049         ReadMoNetConfig(MONET7_CONFIG);
00050         ReadMoNetCommandConfig(MONETCMD7_CONFIG);
00051     } else {
00052         OSYSLOG1((osyslogERROR,
00053                   "MoNet::DoInit() UNKNOWN ROBOT DESIGN"));
00054     }
00055 
00056     return oSUCCESS;
00057 }
00058 
00059 OStatus
00060 MoNet::DoStart(const OSystemEvent& event)
00061 {
00062     moNetState = MNS_START;
00063 
00064     ENABLE_ALL_SUBJECT;
00065     ASSERT_READY_TO_ALL_OBSERVER;
00066 
00067     return oSUCCESS;
00068 }
00069 
00070 OStatus
00071 MoNet::DoStop(const OSystemEvent& event)
00072 {
00073     moNetState = MNS_IDLE;
00074 
00075     DISABLE_ALL_SUBJECT;
00076     DEASSERT_READY_TO_ALL_OBSERVER;
00077 
00078     return oSUCCESS;
00079 }
00080 
00081 OStatus
00082 MoNet::DoDestroy(const OSystemEvent& event)
00083 {
00084     DELETE_ALL_SUBJECT_AND_OBSERVER;
00085     return oSUCCESS;
00086 }
00087 
00088 void
00089 MoNet::NotifyClientCommand(const ONotifyEvent& event)
00090 {
00091     MoNetCommand* cmd = (MoNetCommand*)event.Data(0);
00092 
00093     if (moNetState == MNS_IDLE) {
00094 
00095         ; // do nothing
00096 
00097     } else if (moNetState == MNS_START) {
00098 
00099         currentCommandID = Execute(cmd->commandID);
00100         if (currentCommandID != monetcommandID_UNDEF) {
00101             moNetState = MNS_AGENT_RUNNING;
00102         } else {
00103             OSYSLOG1((osyslogERROR,
00104                       "INVALID MoNetCommandID %d", cmd->commandID));
00105             ReplyClientResult(cmd->commandID,
00106                               monetINVALID_ARG, currentPosture);
00107         }
00108 
00109         observer[event.ObsIndex()]->AssertReady();
00110 
00111     } else if (moNetState == MNS_AGENT_RUNNING) {
00112 
00113         ReplyClientResult(cmd->commandID, monetBUSY, monetpostureUNDEF);
00114         observer[event.ObsIndex()]->AssertReady();
00115     }
00116 }
00117 
00118 void
00119 MoNet::NotifyAgentResult(const ONotifyEvent& event)
00120 {
00121     MoNetAgentResult* result = (MoNetAgentResult*)event.Data(0);
00122 
00123     OSYSPRINT(("AGENT RESULT : agent %d index %d status %d endPos %d\n",
00124                result->agent, result->index,
00125                result->status, result->endPosture));
00126 
00127     if (moNetState == MNS_IDLE) {
00128 
00129         ; // do nothing
00130 
00131     } else if (moNetState == MNS_START) {
00132 
00133         OSYSLOG1((osyslogERROR,
00134                   "MoNet::NotifyAgentResult() : moNetState ERROR %d %d %d %d",
00135                   result->agent, result->index,
00136                   result->status, result->endPosture));
00137 
00138         observer[event.ObsIndex()]->AssertReady();
00139 
00140     } else if (moNetState == MNS_AGENT_RUNNING) {
00141 
00142         MoNetCommandInfo* cinfo = commandArcPath.front().CommandInfo();
00143         cinfo->SetAgentResult(result->agent, result->index, result->status);
00144         if (cinfo->IsDone() == true) {
00145             
00146             MoNetPosture endpos = cinfo->EndPosture();
00147             if (endpos != monetpostureANY) currentPosture = endpos;
00148                 
00149             cinfo->ClearAgentResult();
00150             commandArcPath.pop_front();
00151         
00152             if (commandArcPath.size() == 0) {
00153                 ReplyClientResult(currentCommandID,
00154                                   result->status,
00155                                   currentPosture);
00156                 moNetState = MNS_START;
00157             } else {
00158                 cinfo = commandArcPath.front().CommandInfo();
00159                 ExecuteCommandInfo(cinfo);
00160             }
00161         }
00162 
00163         observer[event.ObsIndex()]->AssertReady();
00164     }
00165 }
00166 
00167 void
00168 MoNet::LoadMotionODA()
00169 {
00170     OSYSDEBUG(("LoadMotionODA()\n"));
00171 
00172     OStatus result;
00173     byte*   addr;
00174     size_t  size;
00175 
00176     result = OPENR::FindDesignData(MONET_MOTION_KEYWORD,
00177                                    &motionDataID, &addr, &size);
00178     if (result != oSUCCESS) {
00179         OSYSLOG1((osyslogERROR, "%s : %s %d",
00180                   "MoNet::LoadMotionODA()",
00181                   "OPENR::FindDesignData() FAILED", result));
00182         return;
00183     }
00184 
00185     motionODA.Set(addr);
00186 }
00187 
00188 void
00189 MoNet::LoadSoundODA()
00190 {
00191     OSYSDEBUG(("LoadSoundODA()\n"));
00192 
00193     OStatus result;
00194     byte*   addr;
00195     size_t  size;
00196 
00197     result = OPENR::FindDesignData(MONET_SOUND_KEYWORD,
00198                                    &soundDataID, &addr, &size);
00199     if (result != oSUCCESS) {
00200         OSYSLOG1((osyslogERROR, "%s : %s %d",
00201                   "MoNet::LoadSoundODA()",
00202                   "OPENR::FindDesignData() FAILED", result));
00203         return;
00204     }
00205 
00206     soundODA.Set(addr);
00207 }
00208 
00209 void
00210 MoNet::ReadMoNetConfig(const char* path)
00211 {
00212     OSYSDEBUG(("MoNet::ReadMoNetConfig(%s)\n", path));
00213 
00214     char buf[LINEBUFSIZE];
00215     char agt[MONET_AGENT_NAME_MAX+1];
00216     char cmd[MONET_AGENT_COMMAND_NAME_MAX+1];
00217     char idx[NUMBUFSIZE];
00218 
00219     FILE* fp = fopen(path, "r");
00220     if (fp == 0) {
00221         OSYSLOG1((osyslogERROR, "%s : %s %s",
00222                   "MoNet::ReadMoNetConfig()", "can't open", path));
00223         return;
00224     }
00225 
00226     while (fgets(buf, LINEBUFSIZE, fp) != 0) {
00227         if (buf[0] == '#') continue; // skip comment line
00228         strcpy(agt, strtok(buf, " \t"));
00229         strcpy(cmd, strtok(0, " \t"));
00230         strcpy(idx, strtok(0, " \t"));
00231 
00232         MoNetAgentID agent, start, end;
00233         int index;
00234 
00235         agent = ToMoNetAgentID(agt);
00236         if (agent == monetagentSOUND) {
00237             index = ToCommandIndex(soundODA, cmd, idx);
00238             start = monetpostureANY;
00239             end   = monetpostureANY;
00240 
00241         } else {
00242             index = ToCommandIndex(motionODA, cmd, idx);
00243             start = ToStartPosture(cmd);
00244             end   = ToEndPosture(cmd);
00245         }
00246 
00247         MoNetCommandInfo* info = moNetCommandInfoManager.New();
00248         info->SetAgentCommand(agent, index, start, end);
00249         if (info->StartPosture() != monetpostureANY &&
00250             info->StartPosture() != info->EndPosture()) {
00251             CommandArc arc(start, end, info);
00252             moNet.Add(arc);
00253         }
00254     }
00255 
00256     fclose(fp);
00257 
00258     moNet.Print();
00259 }
00260 
00261 void
00262 MoNet::ReadMoNetCommandConfig(const char* path)
00263 {
00264     OSYSDEBUG(("MoNet::ReadMoNetCommandConfig(%s)\n", path));
00265 
00266     char buf[LINEBUFSIZE];
00267     char cmdID[NUMBUFSIZE];
00268     char numagt[NUMBUFSIZE];
00269     char synckey[NUMBUFSIZE];
00270     char agt[MONET_AGENT_NAME_MAX+1];
00271     char cmd[MONET_AGENT_COMMAND_NAME_MAX+1];
00272     char idx[NUMBUFSIZE];
00273 
00274     FILE* fp = fopen(path, "r");
00275     if (fp == 0) {
00276         OSYSLOG1((osyslogERROR, "%s : %s %s",
00277                   "MoNet::ReadMoNetConfig()", "can't open", path));
00278         return;
00279     }
00280 
00281     while (fgets(buf, LINEBUFSIZE, fp) != 0) {
00282 
00283         if (buf[0] == '#') continue; // skip comment line
00284 
00285         strcpy(cmdID,   strtok(buf, " \t"));
00286         strcpy(numagt,  strtok(0, " \t"));
00287         strcpy(synckey, strtok(0, " \t"));
00288 
00289         MoNetCommandID id    = (MoNetCommandID)atoi(cmdID);
00290         int numAgentCommands = atoi(numagt);
00291         bool useSyncKey      = (synckey[0] == '0') ? false : true;
00292         OSYSPRINT(("commandID %d numAgentCommands %d useSyncKey %d\n",
00293                    id, numAgentCommands, useSyncKey));
00294 
00295         MoNetCommandInfo* info = moNetCommandInfoManager.New(id, useSyncKey);
00296         
00297         int n = 0;
00298         while (n != numAgentCommands && fgets(buf, LINEBUFSIZE, fp) != 0) {
00299 
00300             if (buf[0] == '#') continue; // skip comment line
00301 
00302             strcpy(agt, strtok(buf, " \t"));
00303             strcpy(cmd, strtok(0, " \t"));
00304             strcpy(idx, strtok(0, " \t"));
00305 
00306             MoNetAgentID agent, start, end;
00307             int index;
00308 
00309             agent = ToMoNetAgentID(agt);
00310             if (agent == monetagentSOUND) {
00311                 index = ToCommandIndex(soundODA, cmd, idx);
00312                 start = monetpostureANY;
00313                 end   = monetpostureANY;
00314             } else {
00315                 index = ToCommandIndex(motionODA, cmd, idx);
00316                 start = ToStartPosture(cmd);
00317                 end   = ToEndPosture(cmd);
00318             }
00319 
00320             info->SetAgentCommand(agent, index, start, end);
00321             n++;
00322         }
00323 
00324         if (info->StartPosture() != monetpostureANY &&
00325             info->StartPosture() != info->EndPosture()) {
00326             CommandArc arc(info->StartPosture(), info->EndPosture(), info);
00327             moNet.Add(arc);
00328         }
00329     }
00330 
00331     fclose(fp);
00332 
00333     moNet.Print();
00334 }
00335 
00336 MoNetAgentID
00337 MoNet::ToMoNetAgentID(char* agt)
00338 {
00339     if (strcmp(agt, monetagentMTN_STRNAME) == 0) {
00340         return monetagentMTN;
00341     } else if (strcmp(agt, monetagentSOUND_STRNAME) == 0) {
00342         return monetagentSOUND;
00343     } else if (strcmp(agt, monetagentNEUTRAL_STRNAME) == 0) {
00344         return monetagentNEUTRAL;
00345     } else if (strcmp(agt, monetagentMTNWALK_STRNAME) == 0) {
00346         return monetagentMTNWALK;
00347     } else {
00348         return monetagentUNDEF;
00349     }
00350 }
00351 
00352 int
00353 MoNet::ToCommandIndex(const ODA& oda, char* cmd, char* idx)
00354 {
00355     int index = atoi(idx);
00356     if (index >= 0) {
00357         return index;
00358     } else {
00359         for (int i = 0; i < oda.GetNumFiles(); i++) {
00360             if (oda.GetMagic(i) == ODA_MAGIC_OMTN) {
00361 
00362                 MTNFile* mtnfile = (MTNFile*)oda.GetData(i);
00363                 if (strcmp(mtnfile->GetName(), cmd) == 0) {
00364                     OSYSPRINT(("%s %d\n", cmd, i));
00365                     return i;
00366                 }
00367 
00368             } else {
00369 
00370                 if (strcmp(oda.GetName(i), cmd) == 0) {
00371                     OSYSPRINT(("%s %d\n", cmd, i));
00372                     return i;
00373                 }
00374 
00375             }
00376         }
00377     }
00378 
00379     OSYSPRINT(("%s -1\n", cmd));
00380     return -1;
00381 }
00382 
00383 MoNetPosture
00384 MoNet::ToStartPosture(char* cmd)
00385 {
00386     char buf[MONET_AGENT_COMMAND_NAME_MAX+1];
00387     strcpy(buf, cmd);
00388 
00389     strtok(buf, "_#");
00390     char* pos = strtok(0, "_#");
00391     
00392     return ToPosture(pos);
00393 }
00394 
00395 MoNetPosture
00396 MoNet::ToEndPosture(char* cmd)
00397 {
00398     char buf[MONET_AGENT_COMMAND_NAME_MAX+1];
00399     strcpy(buf, cmd);
00400 
00401     strtok(buf, "_#");
00402     strtok(0, "_#");
00403     char* pos = strtok(0, "_#");
00404 
00405     return ToPosture(pos);
00406 }
00407 
00408 MoNetPosture
00409 MoNet::ToPosture(char* pos)
00410 {
00411     if (strcmp(pos, "stand") == 0) {
00412         return monetpostureSTAND;
00413     } else if (strcmp(pos, "sit") == 0) {
00414         return monetpostureSIT;
00415     } else if (strcmp(pos, "sleep") == 0) {
00416         return monetpostureSLEEP;
00417     } else if (strcmp(pos, "walk") == 0) {
00418         return monetpostureWALK;
00419     } else if (strcmp(pos, "any") == 0) {
00420         return monetpostureANY;
00421     } else if (strcmp(pos, "nt") == 0) {
00422         return monetpostureNT;
00423     } else {
00424         return monetpostureUNDEF;
00425     }
00426 }
00427 
00428 MoNetCommandID
00429 MoNet::Execute(MoNetCommandID id)
00430 {
00431     MoNetCommandInfo* cinfo = moNetCommandInfoManager.Find(id);
00432     if (cinfo == 0) {
00433         MoNetResult result(id, monetINVALID_ARG, monetagentUNDEF);
00434         subject[sbjClientResult]->SetData(&result, sizeof(result));
00435         subject[sbjClientResult]->NotifyObservers();
00436         return monetcommandID_UNDEF;
00437     }
00438 
00439     if (cinfo->StartPosture() != currentPosture
00440         && cinfo->StartPosture() != monetpostureANY) {
00441 
00442         int dist = moNet.Search(currentPosture,
00443                                 cinfo->StartPosture(),
00444                                 commandArcPath);
00445         if (dist < 0) {
00446             OSYSLOG1((osyslogERROR,
00447                       "MoNet::Execute() : moNet.Search(%d -> %d) FAILED",
00448                       currentPosture, cinfo->StartPosture()));
00449             return monetcommandID_UNDEF;
00450         }
00451     }
00452 
00453     CommandArc arc(cinfo->StartPosture(), cinfo->EndPosture(), cinfo);
00454     commandArcPath.push_back(arc);
00455     
00456     cinfo = commandArcPath.front().CommandInfo();
00457     ExecuteCommandInfo(cinfo);
00458 
00459     return id;
00460 }
00461 
00462 void
00463 MoNet::ExecuteCommandInfo(MoNetCommandInfo* cinfo)
00464 {
00465     OVRSyncKey dividedSyncKey[ovrsynckeyMAX_NUM_DIVISION];
00466 
00467     if (cinfo->UseSyncKey() == true) {
00468         NewAndDivideSyncKey(cinfo->NumAgentCommands(), dividedSyncKey);
00469     } else {
00470         for (int i = 0; i < cinfo->NumAgentCommands(); i++) {
00471             dividedSyncKey[i] = ovrsynckeyUNDEF;
00472         }
00473     }
00474 
00475     for (int i = 0; i < cinfo->NumAgentCommands(); i++) {
00476 
00477         int sbjidx;
00478         MoNetAgentCommand* agtcmd = cinfo->AgentCommand(i);
00479         agtcmd->syncKey = dividedSyncKey[i];
00480         if (agtcmd->agent == monetagentSOUND) {
00481             sbjidx = sbjSoundAgentCommand;
00482         } else {
00483             sbjidx = sbjMotionAgentCommand;
00484         }
00485 
00486         OSYSDEBUG(("AGENT COMMAND: agent %d index %d syncKey 0x%08x\n", 
00487                    agtcmd->agent, agtcmd->index, agtcmd->syncKey));
00488 
00489         subject[sbjidx]->SetData(agtcmd, sizeof(*agtcmd));
00490         subject[sbjidx]->NotifyObservers();
00491 
00492     }
00493 }
00494 
00495 int
00496 MoNet::NewAndDivideSyncKey(int ndivkey, OVRSyncKey* divkey)
00497 {
00498     OStatus result;
00499 
00500     if (ndivkey > ovrsynckeyMAX_NUM_DIVISION) {
00501         for (int i = 0; i < ndivkey; i++) divkey[i] = ovrsynckeyUNDEF;
00502         return -1;
00503     }
00504 
00505     result = OPENR::NewSyncKey(&divkey[0]);
00506     if (result != oSUCCESS) {
00507         OSYSLOG1((osyslogERROR, "%s : %s %d",
00508                   "MoNet::DivideSyncKey()",
00509                   "OPENR::NewSyncKey() FAILED", result));
00510         for (int i = 0; i < ndivkey; i++) divkey[i] = ovrsynckeyUNDEF;
00511         return -1;
00512     }
00513 
00514     int nkey = 1;
00515     int idxA = 0;
00516     int idxB = 1;
00517     OVRSyncKey keyA;
00518     OVRSyncKey keyB;
00519 
00520     while (nkey < ndivkey) {
00521         result = OPENR::DivideSyncKey(divkey[idxA], &keyA, &keyB);
00522         if (result == oSUCCESS) {
00523 
00524             divkey[idxA] = keyA;
00525             divkey[idxB] = keyB;
00526             OSYSDEBUG(("divkey[%d] 0x%08x divkey[%d] 0x%08x\n",
00527                        idxA, keyA, idxB, keyB));
00528             
00529             idxB++;
00530             nkey++;
00531             OSYSDEBUG(("nkey %d idxA %d idxB %d\n", nkey, idxA, idxB));
00532 
00533         } else {
00534 
00535             //
00536             // divkey[idxA] can't be divided any more.
00537             // So, divkey[idxA+1] will be divided in next loop.
00538             //
00539             idxA++;
00540             OSYSDEBUG(("nkey %d idxA %d idxB %d\n", nkey, idxA, idxB));
00541         }
00542     }
00543 
00544 #ifdef OPENR_DEBUG
00545     for (int i = 0; i < nkey; i++)
00546         OSYSDEBUG(("divkey[%d] 0x%08x\n", i, divkey[i]));
00547 #endif
00548 
00549     return nkey;
00550 }
00551 
00552 void 
00553 MoNet::ReplyClientResult(MoNetCommandID id, MoNetStatus st, MoNetPosture pos)
00554 {
00555     MoNetResult result(id, st, pos);
00556     subject[sbjClientResult]->SetData(&result, sizeof(result));
00557     subject[sbjClientResult]->NotifyObservers();
00558 
00559 }

Generated on Sun Dec 2 23:04:29 2007 for openSDK by  doxygen 1.3.9.1