00001
00002
00003
00004
00005
00006
00007
00008
00009
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 ;
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 ;
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;
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;
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;
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
00537
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 }