72 segmentNumber(segnum),
88 throw std::invalid_argument(
"segmentSpan parameter is negative.");
92 throw std::invalid_argument(
"theirMuscles parameter is negative.");
96 throw std::invalid_argument(
"Our Muscles parameter is negative.");
100 throw std::invalid_argument(
"Edge parameters is negative.");
104 throw std::invalid_argument(
"Segment number is negative.");
108 throw std::invalid_argument(
"control time is negative.");
112 throw std::invalid_argument(
"impedance control tension is negative.");
116 throw std::invalid_argument(
"impedance control position is negative.");
120 throw std::invalid_argument(
"impedance control velocity is negative.");
124 throw std::invalid_argument(
"Control Length is negative.");
135 std::string resourcePath,
139 edgeConfigFilename(ec),
140 nodeConfigFilename(nc),
142 edgeEvolution(args +
"_edge", ec, resourcePath),
144 nodeEvolution(args +
"_node", nc, resourcePath),
148 m_dataObserver(
"logs/TCData"),
154 if (resourcePath !=
"")
156 path = FileHelpers::getResourcePath(resourcePath);
163 nodeConfigData.readFile(path + nodeConfigFilename);
164 edgeConfigData.readFile(path + edgeConfigFilename);
165 nodeLearning = nodeConfigData.getintvalue(
"learning");
166 edgeLearning = edgeConfigData.getintvalue(
"learning");
170 BaseSpineCPGControl::~BaseSpineCPGControl()
190 std::vector<double> state;
194 array_2D nodeParams = scaleNodeActions(nodeAdapter.step(dt, state));
196 setupCPGs(subject, nodeParams, edgeParams);
198 initConditions = subject.getSegmentCOM(m_config.segmentNumber);
199 #ifdef LOGGING // Conditional compile for data logging
200 m_dataObserver.
onSetup(subject);
203 #if (0) // Conditional Compile for debug info
204 std::cout << *m_pCPGSys << std::endl;
213 std::vector <tgSpringCableActuator*> allMuscles = subject.getAllMuscles();
215 for (std::size_t i = 0; i < allMuscles.size(); i++)
218 allMuscles[i]->attach(pStringControl);
220 m_allControllers.push_back(pStringControl);
225 for (std::size_t i = 0; i < m_allControllers.size(); i++)
227 m_allControllers[i]->assignNodeNumber(*m_pCPGSys, nodeActions);
231 for (std::size_t i = 0; i < m_allControllers.size(); i++)
234 assert(pStringInfo != NULL);
241 if (m_config.useDefault)
243 pStringInfo->setupControl(*p_ipc);
247 pStringInfo->setupControl(*p_ipc, m_config.controlLength);
256 if (m_updateTime >= m_config.controlTime)
258 std::size_t numControllers = subject.getNumberofMuslces();
260 double descendingCommand = 2.0;
261 std::vector<double> desComs (numControllers, descendingCommand);
263 m_pCPGSys->
update(desComs, m_updateTime);
264 #ifdef LOGGING // Conditional compile for data logging
265 m_dataObserver.
onStep(subject, m_updateTime);
271 double currentHeight = subject.getSegmentCOM(m_config.segmentNumber)[1];
274 if (currentHeight > 25 || currentHeight < 1.0)
286 std::vector<double> finalConditions = subject.getSegmentCOM(m_config.segmentNumber);
288 const double newX = finalConditions[0];
289 const double newZ = finalConditions[2];
290 const double oldX = initConditions[0];
291 const double oldZ = initConditions[2];
293 const double distanceMoved = sqrt((newX-oldX) * (newX-oldX) +
294 (newZ-oldZ) * (newZ-oldZ));
298 scores.push_back(-1.0);
302 scores.push_back(distanceMoved);
307 double totalEnergySpent=0;
309 std::vector<tgSpringCableActuator* > tmpStrings = subject.getAllMuscles();
311 for(
int i=0; i<tmpStrings.size(); i++)
318 const double previousLength = stringHist.
restLengths[j-1];
319 const double currentLength = stringHist.
restLengths[j];
321 double motorSpeed = (currentLength-previousLength);
324 const double workDone = previousTension * motorSpeed;
325 totalEnergySpent += workDone;
329 scores.push_back(totalEnergySpent);
331 edgeAdapter.endEpisode(scores);
332 nodeAdapter.endEpisode(scores);
337 for(
size_t i = 0; i < m_allControllers.size(); i++)
339 delete m_allControllers[i];
341 m_allControllers.clear();
344 const double BaseSpineCPGControl::getCPGValue(std::size_t i)
const
347 return (*m_pCPGSys)[i];
350 double BaseSpineCPGControl::getScore()
const
352 if (scores.size() == 2)
358 throw std::runtime_error(
"Called before scores were obtained!");
364 (vector< vector <double> > actions)
366 std::size_t numControllers = edgeConfigData.getintvalue(
"numberOfControllers");
369 assert(numControllers == actions.size());
370 assert(actions[0].size() == 2);
372 double lowerLimit = m_config.lowPhase;
373 double upperLimit = m_config.highPhase;
374 double range = upperLimit - lowerLimit;
376 array_4D actionList(boost::extents[m_config.segmentSpan]
377 [m_config.theirMuscles]
378 [m_config.ourMuscles]
391 while (i < m_config.segmentSpan)
393 while(j < m_config.theirMuscles)
395 while(k < m_config.ourMuscles)
399 std::cout <<
"ran out before table populated!"
405 if (i == 1 && j == k)
412 std::vector<double> edgeParam = actions.back();
414 actionList[i][j][k][0] = edgeParam[0];
416 actionList[i][j][k][1] = edgeParam[1] *
417 (range) + lowerLimit;
432 assert(actions.empty());
436 array_2D BaseSpineCPGControl::scaleNodeActions
437 (vector< vector <double> > actions)
439 std::size_t numControllers = nodeConfigData.getintvalue(
"numberOfControllers");
440 std::size_t numActions = nodeConfigData.getintvalue(
"numberOfActions");
442 assert( actions.size() == numControllers);
443 assert( actions[0].size() == numActions);
445 array_2D nodeActions(boost::extents[numControllers][numActions]);
447 array_2D limits(boost::extents[2][numActions]);
450 assert(numActions == 2);
452 limits[0][0] = m_config.lowFreq;
453 limits[1][0] = m_config.highFreq;
454 limits[0][1] = m_config.lowAmp;
455 limits[1][1] = m_config.highAmp;
458 for( std::size_t i = 0; i < numControllers; i++)
460 for( std::size_t j = 0; j < numActions; j++)
462 nodeActions[i][j] = ( actions[i][j] *
463 (limits[1][j] - limits[0][j])) + limits[0][j];
Contains the definition of class ImpedanceControl. $Id$.
virtual void onSetup(BaseSpineModelLearning &subject)
virtual void onStep(BaseSpineModelLearning &subject, double dt)
void update(std::vector< double > &descCom, double dt)
std::deque< double > tensionHistory
virtual void onTeardown(BaseSpineModelLearning &subject)
virtual void setupCPGs(BaseSpineModelLearning &subject, array_2D nodeActions, array_4D edgeActions)
void setConnectivity(const std::vector< tgCPGActuatorControl * > &allStrings, array_4D edgeParams)
Config(int ss, int tm, int om, int param, int segnum=6, double ct=0.1, double la=0, double ha=30, double lp=-1 *M_PI, double hp=M_PI, double kt=0.0, double kp=1000.0, double kv=100.0, bool def=true, double cl=10.0, double lf=0.0, double hf=30.0)
std::deque< double > restLengths
Definition of the tgCPGStringControl observer class.
BaseSpineCPGControl(BaseSpineCPGControl::Config config, std::string args, std::string resourcePath="", std::string ec="edgeConfig.ini", std::string nc="nodeConfig.ini")
A class to read a learning configuration from a .ini file.
Contains the definition of abstract base class tgSpringCableActuator. Assumes that the string is line...
A series of functions to assist with file input/output.
Contains the definition of class AnnealEvolution. Adapting NeuroEvolution to do Simulated Annealing...
virtual array_4D scaleEdgeActions(std::vector< std::vector< double > > actions)
A controller for the template class BaseSpineModelLearning.
Definition of class CPGEquations.
virtual void onStep(tgModel &model, double dt)
Definition of class CPGNode.
void initialize(AnnealEvolution *evo, bool isLearning, configuration config)
virtual void onSetup(tgModel &model)
void notifyStep(double dt)