ResetServos.cc
Go to the documentation of this file.00001 #include "Shared/RobotInfo.h"
00002 #ifdef TGT_IS_BIOLOID
00003
00004 #include "Behaviors/BehaviorBase.h"
00005 #include "Events/EventRouter.h"
00006 #include "Events/LocomotionEvent.h"
00007 #include "Motion/MMAccessor.h"
00008 #include "Motion/MotionManager.h"
00009 #include "Motion/MotionSequenceMC.h"
00010 #include "Motion/PIDMC.h"
00011 #include "Motion/PostureMC.h"
00012 #include "Shared/WorldState.h"
00013 #include "local/DeviceDrivers/DynamixelProtocol.h"
00014 #include "IPC/SharedObject.h"
00015
00016
00017
00018 class ResetServos : public BehaviorBase {
00019 public:
00020 ResetServos() : BehaviorBase("ResetServos"), pidmc_id(MotionManager::invalid_MC_ID) {}
00021
00022 virtual void doStart() {
00023 pidmc_id = motman->addPersistentMotion(SharedObject<PIDMC>(), MotionManager::kHighPriority);
00024 erouter->addListener(this, EventBase::servoEGID);
00025 #ifdef TGT_HAS_LEGS
00026 erouter->addListener(this, EventBase::locomotionEGID);
00027 #endif
00028 }
00029
00030 virtual void doStop() {
00031 motman->removeMotion(pidmc_id);
00032 }
00033
00034 static const unsigned int loadErrorDownTime = 2500;
00035 static const unsigned int heatErrorDownTime = 5000;
00036 static const unsigned int fidgetInterval = 10000;
00037
00038 virtual void doEvent() {
00039 switch ( event->getGeneratorID() ) {
00040
00041 case EventBase::servoEGID: {
00042 const unsigned int joint = event->getSourceID();
00043 if ( MMAccessor<PIDMC>(pidmc_id)->getPID(joint).weight > 0 )
00044 return;
00045 unsigned char errorCode = (unsigned char)event->getMagnitude();
00046 if ( (errorCode & DynamixelProtocol::LOAD_ERROR) && std::abs(state->pidduties[joint]) > 0.05 )
00047 erouter->addTimer(this, joint, loadErrorDownTime, false);
00048 else if ( errorCode & DynamixelProtocol::HEAT_ERROR )
00049 erouter->addTimer(this, joint+1000, heatErrorDownTime, false);
00050 else return;
00051 std::cout << "Joint " << joint << " (" << outputNames[joint] << ") reported ";
00052 for(unsigned int i=0; i<sizeof(errorCode)*8; ++i)
00053 if( (errorCode>>i) & 1 )
00054 std::cout << DynamixelProtocol::ResponseErrorNames[i];
00055 std::cout << ", pidduty=" << state->pidduties[joint] << std::endl;
00056 MMAccessor<PIDMC>(pidmc_id)->setJointPowerLevel(joint, 0, 1);
00057 break;
00058 }
00059
00060 #ifdef TGT_HAS_LEGS
00061 case EventBase::locomotionEGID: {
00062 const LocomotionEvent& le = dynamic_cast<const LocomotionEvent&>(*event);
00063 if ( le.x == 0 && le.y == 0 && le.a == 0 )
00064 erouter->addTimer(this, 9999, fidgetInterval, true);
00065 else
00066 erouter->removeTimer(this, 9999);
00067
00068 break;
00069 }
00070 #endif
00071
00072 case EventBase::timerEGID: {
00073 unsigned int source = event->getSourceID();
00074 #ifdef TGT_HAS_LEGS
00075 if ( source == 9999 ) {
00076 twitchSomeLeg();
00077 return;
00078 }
00079 #endif
00080 bool loadError = source < 1000;
00081 unsigned int joint = loadError ? source : source-1000;
00082 MMAccessor<PIDMC>(pidmc_id)->setJointPowerLevel(joint, 0, 0);
00083
00084 if ( loadError) {
00085
00086 float curpos = state->outputs[joint];
00087 SharedObject<PostureMC> twitch_mc;
00088 twitch_mc->setOutputCmd(joint, curpos*state->pidduties[joint]);
00089 motman->addPrunableMotion(twitch_mc, MotionManager::kHighPriority);
00090 }
00091 break;
00092 }
00093
00094 default:
00095 std::cout << "Unexpected event " << event->getDescription() << std::endl;
00096 break;
00097 }
00098 }
00099
00100 #ifdef TGT_HAS_LEGS
00101 void twitchSomeLeg() {
00102 unsigned int joint = 0;
00103 for(unsigned int i = LegOffset; i < LegOffset+NumLegJoints; i++)
00104 if ( fabs(state->pidduties[i]) > fabs(state->pidduties[joint]) )
00105 joint=i;
00106 if( fabs(state->pidduties[joint]) < 0.2)
00107 return;
00108 unsigned int leg = (joint-LegOffset)/JointsPerLeg;
00109 unsigned int elevator = LegOffset + leg*JointsPerLeg + ElevatorOffset;
00110
00111
00112 float curpos = state->outputs[elevator];
00113 float newpos = 1.3f;
00114
00115 SharedObject<TinyMotionSequenceMC> fidget_mc;
00116 fidget_mc->advanceTime(700);
00117 fidget_mc->setOutputCmd(joint,newpos);
00118 fidget_mc->advanceTime(300);
00119 fidget_mc->setOutputCmd(joint,curpos);
00120 motman->addPrunableMotion(fidget_mc,MotionManager::kHighPriority);
00121 }
00122 #endif
00123
00124 private:
00125 MotionManager::MC_ID pidmc_id;
00126
00127 };
00128
00129 REGISTER_BEHAVIOR_MENU_OPT(ResetServos,"Background Behaviors/System Daemons",BEH_NONEXCLUSIVE|BEH_START);
00130
00131 #endif