00001 /*!@file SupplementaryMotorAreaI.C generate a sequance of movment for the robot to follow */ 00002 //This is the controller which will have a path to follow 00003 00004 00005 00006 //////////////////////////////////////////////////////////////////// // 00007 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2001 by the // 00008 // University of Southern California (USC) and the iLab at USC. // 00009 // See http://iLab.usc.edu for information about this project. // 00010 // //////////////////////////////////////////////////////////////////// // 00011 // Major portions of the iLab Neuromorphic Vision Toolkit are protected // 00012 // under the U.S. patent ``Computation of Intrinsic Perceptual Saliency // 00013 // in Visual Environments, and Applications'' by Christof Koch and // 00014 // Laurent Itti, California Institute of Technology, 2001 (patent // 00015 // pending; application number 09/912,225 filed July 23, 2001; see // 00016 // http://pair.uspto.gov/cgi-bin/final/home.pl for current status). // 00017 // //////////////////////////////////////////////////////////////////// // 00018 // This file is part of the iLab Neuromorphic Vision C++ Toolkit. // 00019 // // 00020 // The iLab Neuromorphic Vision C++ Toolkit is free software; you can // 00021 // redistribute it and/or modify it under the terms of the GNU General // 00022 // Public License as published by the Free Software Foundation; either // 00023 // version 2 of the License, or (at your option) any later version. // 00024 // // 00025 // The iLab Neuromorphic Vision C++ Toolkit is distributed in the hope // 00026 // that it will be useful, but WITHOUT ANY WARRANTY; without even the // 00027 // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // 00028 // PURPOSE. See the GNU General Public License for more details. // 00029 // // 00030 // You should have received a copy of the GNU General Public License // 00031 // along with the iLab Neuromorphic Vision C++ Toolkit; if not, write // 00032 // to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, // 00033 // Boston, MA 02111-1307 USA. // 00034 // //////////////////////////////////////////////////////////////////// // 00035 // 00036 // Primary maintainer for this file: Lior Elazary <lelazary@yahoo.com> 00037 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/Robots/RobotBrain/SupplementaryMotorAreaI.C $ 00038 // $Id: SupplementaryMotorAreaI.C 10794 2009-02-08 06:21:09Z itti $ 00039 // 00040 00041 #include "Component/ModelManager.H" 00042 #include "Media/FrameSeries.H" 00043 #include "Transport/FrameInfo.H" 00044 #include "Raster/GenericFrame.H" 00045 #include "Image/Image.H" 00046 #include "GUI/ImageDisplayStream.H" 00047 #include "Robots/RobotBrain/SupplementaryMotorAreaI.H" 00048 00049 00050 // ###################################################################### 00051 SupplementaryMotorAreaI::SupplementaryMotorAreaI(OptionManager& mgr, 00052 const std::string& descrName, const std::string& tagName) : 00053 ModelComponent(mgr, descrName, tagName), 00054 itsCurrentState(new RobotSimEvents::StateMessage), 00055 itsGoalState(new RobotSimEvents::StateMessage), 00056 itsGoalProgress(new RobotSimEvents::GoalProgressMessage), 00057 itsCurrentAction(new RobotSimEvents::ActionMessage), 00058 itsTransPID(1.0f, 0.0, 0.0, //PID 00059 -20, 20, //iMin and iMax 00060 0, 0, 0, //ErrThreash //posThreash //negThresh, 00061 1, -1), //max and min motor commands 00062 itsRotPID(0.60f, 0.0, 0.0, //PID 00063 -20, 20, //iMin and iMax 00064 0, 0, 0, //ErrThreash //posThreash //negThresh, 00065 1, -1) //max and min motor commands 00066 { 00067 00068 itsGoalState->xPos = 0; 00069 itsGoalState->yPos = 0; 00070 itsGoalState->orientation = 0; 00071 00072 itsCurrentState->xPos = 0; 00073 itsCurrentState->yPos = 0; 00074 itsCurrentState->orientation = 0; 00075 00076 } 00077 00078 // ###################################################################### 00079 SupplementaryMotorAreaI::~SupplementaryMotorAreaI() 00080 { 00081 SimEventsUtils::unsubscribeSimEvents(itsTopicsSubscriptions, itsObjectPrx); 00082 } 00083 00084 // ###################################################################### 00085 void SupplementaryMotorAreaI::init(Ice::CommunicatorPtr ic, Ice::ObjectAdapterPtr adapter) 00086 { 00087 Ice::ObjectPtr objPtr = this; 00088 itsObjectPrx = adapter->add(objPtr, 00089 ic->stringToIdentity("SupplementaryMotorArea")); 00090 00091 00092 IceStorm::TopicPrx topicPrx; 00093 00094 itsTopicsSubscriptions.push_back(SimEventsUtils::TopicInfo("StateMessageTopic", topicPrx)); 00095 itsTopicsSubscriptions.push_back(SimEventsUtils::TopicInfo("GoalStateMessageTopic", topicPrx)); 00096 00097 SimEventsUtils::initSimEvents(ic, itsObjectPrx, itsTopicsSubscriptions); 00098 00099 itsActionEventsPub = RobotSimEvents::EventsPrx::uncheckedCast( 00100 SimEventsUtils::getPublisher(ic, "ActionMessageTopic") 00101 ); 00102 00103 itsGoalProgressEventsPub = RobotSimEvents::EventsPrx::uncheckedCast( 00104 SimEventsUtils::getPublisher(ic, "GoalProgressMessageTopic") 00105 ); 00106 00107 IceUtil::ThreadPtr thread = this; 00108 thread->start(); 00109 00110 usleep(10000); 00111 } 00112 00113 // ###################################################################### 00114 void SupplementaryMotorAreaI::run() 00115 { 00116 00117 while(1) 00118 { 00119 evolve(); 00120 usleep(10000); 00121 } 00122 00123 } 00124 00125 // ###################################################################### 00126 void SupplementaryMotorAreaI::updateMessage(const RobotSimEvents::EventMessagePtr& eMsg, 00127 const Ice::Current&) 00128 { 00129 if(eMsg->ice_isA("::RobotSimEvents::StateMessage")) 00130 { 00131 RobotSimEvents::StateMessagePtr stateMsg = RobotSimEvents::StateMessagePtr::dynamicCast(eMsg); 00132 itsCurrentState->xPos = stateMsg->xPos; 00133 itsCurrentState->yPos = stateMsg->yPos; 00134 itsCurrentState->orientation = stateMsg->orientation; 00135 } else if(eMsg->ice_isA("::RobotSimEvents::GoalStateMessage")) 00136 { 00137 RobotSimEvents::GoalStateMessagePtr goalStateMsg = RobotSimEvents::GoalStateMessagePtr::dynamicCast(eMsg); 00138 itsGoalState->xPos = goalStateMsg->xPos; 00139 itsGoalState->yPos = goalStateMsg->yPos; 00140 itsGoalState->orientation = goalStateMsg->orientation; 00141 } 00142 } 00143 00144 // ###################################################################### 00145 void SupplementaryMotorAreaI::evolve() 00146 { 00147 00148 00149 double err = (itsGoalState->xPos-itsCurrentState->xPos)*(itsGoalState->xPos-itsCurrentState->xPos); 00150 err += (itsGoalState->yPos-itsCurrentState->yPos)*(itsGoalState->yPos-itsCurrentState->yPos); 00151 err = sqrt(err); 00152 00153 LDEBUG("Desired: %fx%fx%f pos %fx%fx%f err=%0.2f", 00154 itsGoalState->xPos, itsGoalState->yPos, itsGoalState->orientation, 00155 itsCurrentState->xPos, itsCurrentState->yPos, itsCurrentState->orientation, 00156 err); 00157 00158 itsCurrentAction->transVel = 0.0; 00159 itsCurrentAction->rotVel = 0; 00160 00161 00162 if (err < 0.1F) //err is 10 cm 00163 { 00164 itsGoalProgress->err = -1; 00165 LDEBUG("Goal reached, next"); 00166 } else { 00167 00168 itsGoalProgress->err = err; 00169 float desiredHeading = 00170 atan2((itsGoalState->yPos-itsCurrentState->yPos),(itsGoalState->xPos-itsCurrentState->xPos)); 00171 desiredHeading += M_PI; 00172 //if (desiredHeading > M_PI*2) desiredHeading -= M_PI*2; 00173 00174 00175 //We basicly want the err to be 0, so if its not then we need to move 00176 itsCurrentAction->transVel = itsTransPID.update(err, 0); 00177 //LINFO("Trans %f", itsDesiredTransVel); 00178 if (itsCurrentAction->transVel > 0.2) 00179 itsCurrentAction->transVel = 0.2; 00180 00181 Angle g(desiredHeading); 00182 Angle c(itsCurrentState->orientation); 00183 Angle e = itsRotPID.update(g, c); 00184 LDEBUG("%f-%f =>%f", desiredHeading*180/M_PI, itsCurrentState->orientation*180/M_PI, e.getVal()); 00185 00186 itsCurrentAction->rotVel = (double)e.getVal(); 00187 00188 //The more steering we need, the less we should move 00189 //If we are moving straight, the move the fastest, 00190 //If all we need is to turn, then turn in place 00191 itsCurrentAction->transVel -= fabs(e.getVal()); //the more sterring we need, the less we should move 00192 if (itsCurrentAction->transVel < 0) 00193 itsCurrentAction->transVel = 0; 00194 //If we are moveing 00195 } 00196 00197 LDEBUG("Setting action to transVel=%f rotVel=%f", 00198 itsCurrentAction->transVel, 00199 itsCurrentAction->rotVel); 00200 00201 itsActionEventsPub->updateMessage(itsCurrentAction); 00202 itsGoalProgressEventsPub->updateMessage(itsGoalProgress); 00203 00204 }