37 #include "examples/learningSpines/tgCPGCableControl.h"
46 #include "examples/learningSpines/tgCPGCableControl.h"
48 #include "neuralNet/Neural Network v2/neuralNetwork.h"
50 #include <json/json.h>
87 lp, hp, kt, kp, kv, def, cl, lf, hf),
88 freqFeedbackMin(ffMin),
89 freqFeedbackMax(ffMax),
90 ampFeedbackMin(afMin),
91 ampFeedbackMax(afMax),
92 phaseFeedbackMin(pfMin),
93 phaseFeedbackMax(pfMax),
106 std::string resourcePath) :
114 JSONMixedLearningControl::~JSONMixedLearningControl()
126 bool parsingSuccessful = reader.parse( FileHelpers::getFileString(controlFilename.c_str()), root );
127 if ( !parsingSuccessful )
130 std::cout <<
"Failed to parse configuration\n"
131 << reader.getFormattedErrorMessages();
132 throw std::invalid_argument(
"Bad filename for JSON");
136 Json::Value nodeVals = root.get(
"nodeVals",
"UTF-8");
137 Json::Value startingEdgeVals = root.get(
"startingEdgeVals",
"UTF-8");
138 Json::Value middleEdgeVals = root.get(
"middleEdgeVals",
"UTF-8");
139 Json::Value endingEdgeVals = root.get(
"endingEdgeVals",
"UTF-8");
141 std::cout << nodeVals << std::endl;
143 nodeVals = nodeVals.get(
"params",
"UTF-8");
144 startingEdgeVals = startingEdgeVals.get(
"params",
"UTF-8");
145 middleEdgeVals = middleEdgeVals.get(
"params",
"UTF-8");
146 endingEdgeVals = endingEdgeVals.get(
"params",
"UTF-8");
151 array_2D nodeParams = scaleNodeActions(nodeVals);
153 setupCPGs(subject, nodeParams, startingEdgeParams, middleEdgeParams, endingEdgeParams);
155 Json::Value feedbackParams = root.get(
"feedbackVals",
"UTF-8");
156 feedbackParams = feedbackParams.get(
"params",
"UTF-8");
159 m_config.numStates = feedbackParams.get(
"numStates",
"UTF-8").asInt();
160 m_config.numActions = feedbackParams.get(
"numActions",
"UTF-8").asInt();
161 m_config.numHidden = feedbackParams.get(
"numHidden",
"UTF-8").asInt();
163 std::string nnFile = controlFilePath + feedbackParams.get(
"neuralFilename",
"UTF-8").asString();
165 nn =
new neuralNetwork(m_config.numStates, m_config.numHidden, m_config.numActions);
167 nn->loadWeights(nnFile.c_str());
169 initConditions = subject.getSegmentCOM(m_config.segmentNumber);
170 for (
int i = 0; i < initConditions.size(); i++)
172 std::cout << initConditions[i] <<
" ";
174 std::cout << std::endl;
175 #ifdef LOGGING // Conditional compile for data logging
176 m_dataObserver.
onSetup(subject);
179 #if (0) // Conditional Compile for debug info
180 std::cout << *m_pCPGSys << std::endl;
189 if (m_updateTime >= m_config.controlTime)
192 std::vector<double> desComs = getFeedback(subject);
195 std::size_t numControllers = subject.getNumberofMuslces() * 3;
197 double descendingCommand = 0.0;
198 std::vector<double> desComs (numControllers, descendingCommand);
202 m_pCPGSys->
update(desComs, m_updateTime);
204 catch (std::runtime_error& e)
211 #ifdef LOGGING // Conditional compile for data logging
212 m_dataObserver.
onStep(subject, m_updateTime);
218 double currentHeight = subject.getSegmentCOM(m_config.segmentNumber)[1];
221 if (currentHeight > m_config.maxHeight || currentHeight < m_config.minHeight)
225 throw std::runtime_error(
"Height out of range");
234 std::vector<double> finalConditions = subject.getSegmentCOM(m_config.segmentNumber);
236 const double newX = finalConditions[0];
237 const double newZ = finalConditions[2];
238 const double oldX = initConditions[0];
239 const double oldZ = initConditions[2];
241 const double distanceMoved = sqrt((newX-oldX) * (newX-oldX) +
242 (newZ-oldZ) * (newZ-oldZ));
246 scores.push_back(-1.0);
250 scores.push_back(distanceMoved);
255 double totalEnergySpent=0;
257 std::vector<tgSpringCableActuator* > tmpStrings = subject.getAllMuscles();
259 for(std::size_t i=0; i<tmpStrings.size(); i++)
266 const double previousLength = stringHist.
restLengths[j-1];
267 const double currentLength = stringHist.
restLengths[j];
269 double motorSpeed = (currentLength-previousLength);
272 const double workDone = previousTension * motorSpeed;
273 totalEnergySpent += workDone;
277 scores.push_back(totalEnergySpent);
279 std::cout <<
"Dist travelled " << scores[0] << std::endl;
284 bool parsingSuccessful = reader.parse( FileHelpers::getFileString(controlFilename.c_str()), root );
285 if ( !parsingSuccessful )
288 std::cout <<
"Failed to parse configuration\n"
289 << reader.getFormattedErrorMessages();
290 throw std::invalid_argument(
"Bad filename for JSON");
293 Json::Value prevScores = root.get(
"scores", Json::nullValue);
295 Json::Value subScores;
296 subScores[
"distance"] = scores[0];
297 subScores[
"energy"] = totalEnergySpent;
299 prevScores.append(subScores);
300 root[
"scores"] = prevScores;
303 payloadLog.open(controlFilename.c_str(),ofstream::out);
305 payloadLog << root << std::endl;
311 for(
size_t i = 0; i < m_startingControllers.size(); i++)
313 delete m_startingControllers[i];
315 m_startingControllers.clear();
317 for(
size_t i = 0; i < m_middleControllers.size(); i++)
319 delete m_middleControllers[i];
321 m_middleControllers.clear();
323 for(
size_t i = 0; i < m_endingControllers.size(); i++)
325 delete m_endingControllers[i];
327 m_endingControllers.clear();
330 void JSONMixedLearningControl::setupCPGs(
BaseSpineModelLearning& subject, array_2D nodeActions, array_4D startingEdgeActions, array_4D middleEdgeActions, array_4D endingEdgeActions)
337 CPGEquationsFB& m_CPGFBSys = *(tgCast::cast<CPGEquations, CPGEquationsFB>(m_pCPGSys));
339 for (std::size_t i = 0; i < startMuscles.size(); i++)
345 startMuscles[i]->attach(pStringControl);
350 m_startingControllers.push_back(pStringControl);
354 for (std::size_t i = 0; i < m_startingControllers.size(); i++)
357 assert(pStringInfo != NULL);
358 pStringInfo->
setConnectivity(m_startingControllers, startingEdgeActions);
364 if (m_config.useDefault)
366 pStringInfo->setupControl(*p_ipc);
370 pStringInfo->setupControl(*p_ipc, m_config.controlLength);
374 for (std::size_t i = 0; i < middleMuscles.size(); i++)
380 middleMuscles[i]->attach(pStringControl);
385 m_middleControllers.push_back(pStringControl);
389 for (std::size_t i = 0; i < m_middleControllers.size(); i++)
392 assert(pStringInfo != NULL);
399 if (m_config.useDefault)
401 pStringInfo->setupControl(*p_ipc);
405 pStringInfo->setupControl(*p_ipc, m_config.controlLength);
409 for (std::size_t i = 0; i < endMuscles.size(); i++)
415 endMuscles[i]->attach(pStringControl);
420 m_endingControllers.push_back(pStringControl);
424 for (std::size_t i = 0; i < m_endingControllers.size(); i++)
427 assert(pStringInfo != NULL);
434 if (m_config.useDefault)
436 pStringInfo->setupControl(*p_ipc);
440 pStringInfo->setupControl(*p_ipc, m_config.controlLength);
445 array_2D JSONMixedLearningControl::scaleNodeActions (Json::Value actions)
447 std::size_t numControllers = actions.size();
448 std::size_t numActions = actions[0].size();
450 array_2D nodeActions(boost::extents[numControllers][numActions]);
452 array_2D limits(boost::extents[2][numActions]);
455 assert(numActions == 5);
457 limits[0][0] = m_config.lowFreq;
458 limits[1][0] = m_config.highFreq;
459 limits[0][1] = m_config.lowAmp;
460 limits[1][1] = m_config.highAmp;
461 limits[0][2] = m_config.freqFeedbackMin;
462 limits[1][2] = m_config.freqFeedbackMax;
463 limits[0][3] = m_config.ampFeedbackMin;
464 limits[1][3] = m_config.ampFeedbackMax;
465 limits[0][4] = m_config.phaseFeedbackMin;
466 limits[1][4] = m_config.phaseFeedbackMax;
468 Json::Value::iterator nodeIt = actions.begin();
471 for( std::size_t i = 0; i < numControllers; i++)
473 Json::Value nodeParam = *nodeIt;
474 for( std::size_t j = 0; j < numActions; j++)
476 nodeActions[i][j] = ( (nodeParam.get(j, 0.0)).asDouble() *
477 (limits[1][j] - limits[0][j])) + limits[0][j];
488 std::vector<double> feedback;
490 const std::vector<tgSpringCableActuator*>& allCables = subject.getAllMuscles();
492 double *inputs =
new double[m_config.numStates];
494 std::size_t n = allCables.size();
495 for(std::size_t i = 0; i != n; i++)
497 std::vector< std::vector<double> > actions;
500 std::vector<double > state = getCableState(cable);
503 for (std::size_t i = 0; i < state.size(); i++)
505 inputs[i]=state[i] / 2.0 + 0.5;
508 double *output =
nn->feedForwardPattern(inputs);
509 vector<double> tmpAct;
510 for(
int j=0;j<m_config.numActions;j++)
512 tmpAct.push_back(output[j]);
514 actions.push_back(tmpAct);
516 std::vector<double> cableFeedback = transformFeedbackActions(actions);
518 feedback.insert(feedback.end(), cableFeedback.begin(), cableFeedback.end());
529 std::vector<double> state;
535 const double maxTension = cable.
getConfig().maxTens;
536 state.push_back((cable.
getTension() - maxTension / 2.0) / maxTension);
541 std::vector<double> JSONMixedLearningControl::transformFeedbackActions(std::vector< std::vector<double> >& actions)
544 std::vector<double> feedback;
547 const std::size_t numControllers = 1;
548 const std::size_t numActions = m_config.numActions;
550 assert( actions.size() == numControllers);
551 assert( actions[0].size() == numActions);
554 for( std::size_t i = 0; i < numControllers; i++)
556 for( std::size_t j = 0; j < numActions; j++)
558 feedback.push_back(actions[i][j] * 2.0 - 1.0);
Contains the definition of class ImpedanceControl. $Id$.
void update(std::vector< double > &descCom, double dt)
std::deque< double > tensionHistory
virtual const double getTension() const
virtual const double getStartLength() const
virtual array_4D scaleEdgeActions(Json::Value edgeParam)
void setConnectivity(const std::vector< tgCPGActuatorControl * > &allStrings, array_4D edgeParams)
std::deque< double > restLengths
Definition of the tgCPGStringControl observer class.
A template base class for a tensegrity spine.
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...
virtual void onSetup(BaseSpineModelLearning &subject)
A series of functions to assist with file input/output.
Contains the definition of class AnnealEvolution. Adapting NeuroEvolution to do Simulated Annealing...
Contains the definition of class tgBasicActuator.
JSONMixedLearningControl(JSONMixedLearningControl::Config config, std::string args, std::string resourcePath="")
virtual void onTeardown(BaseSpineModelLearning &subject)
const Config & getConfig() const
std::vector< T * > find(const tgTagSearch &tagSearch)
virtual void onStep(tgModel &model, double dt)
A controller for the template class BaseSpineModelLearning.
Definition of class CPGEquationsFB.
virtual void onSetup(tgModel &model)
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, double ffMin=0.0, double ffMax=0.0, double afMin=0.0, double afMax=0.0, double pfMin=0.0, double pfMax=0.0, double maxH=25.0, double minH=1.0)
virtual const double getCurrentLength() const
virtual void onStep(BaseSpineModelLearning &subject, double dt)
void notifyStep(double dt)
void assignNodeNumberFB(CPGEquationsFB &CPGSys, array_2D nodeParams)