27 #include "JSONQuadCPGControl.h"
38 #include "examples/learningSpines/tgCPGCableControl.h"
47 #include <json/json.h>
76 segmentNumber(segnum),
92 throw std::invalid_argument(
"segmentSpan parameter is negative.");
96 throw std::invalid_argument(
"theirMuscles parameter is negative.");
100 throw std::invalid_argument(
"Our Muscles parameter is negative.");
104 throw std::invalid_argument(
"Edge parameters is negative.");
108 throw std::invalid_argument(
"Segment number is negative.");
112 throw std::invalid_argument(
"control time is negative.");
116 throw std::invalid_argument(
"impedance control tension is negative.");
120 throw std::invalid_argument(
"impedance control position is negative.");
124 throw std::invalid_argument(
"impedance control velocity is negative.");
128 throw std::invalid_argument(
"Control Length is negative.");
139 std::string resourcePath) :
142 m_dataObserver(
"logs/TCData"),
146 if (resourcePath !=
"")
152 controlFilePath =
"";
155 controlFilename = controlFilePath + args;
158 JSONQuadCPGControl::~JSONQuadCPGControl()
172 bool parsingSuccessful = reader.parse( FileHelpers::getFileString(controlFilename.c_str()), root );
173 if ( !parsingSuccessful )
176 std::cout <<
"Failed to parse configuration\n"
177 << reader.getFormattedErrorMessages();
178 throw std::invalid_argument(
"Bad filename for JSON");
182 Json::Value nodeVals = root.get(
"nodeVals",
"UTF-8");
183 Json::Value edgeVals = root.get(
"edgeVals",
"UTF-8");
185 nodeVals = nodeVals.get(
"params",
"UTF-8");
186 edgeVals = edgeVals.get(
"params",
"UTF-8");
189 array_2D nodeParams = scaleNodeActions(nodeVals);
191 setupCPGs(subject, nodeParams, edgeParams);
193 initConditions = subject.getSegmentCOM(m_config.segmentNumber);
194 #ifdef LOGGING // Conditional compile for data logging
195 m_dataObserver.
onSetup(subject);
198 #if (0) // Conditional Compile for debug info
199 std::cout << *m_pCPGSys << std::endl;
208 std::vector <tgSpringCableActuator*> allMuscles = subject.getAllMuscles();
210 for (std::size_t i = 0; i < allMuscles.size(); i++)
217 #endif // Update for kinematic cables
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(std::size_t 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 std::cout <<
"Dist travelled " << scores[0] << std::endl;
336 bool parsingSuccessful = reader.parse( FileHelpers::getFileString(controlFilename.c_str()), root );
337 if ( !parsingSuccessful )
340 std::cout <<
"Failed to parse configuration\n"
341 << reader.getFormattedErrorMessages();
342 throw std::invalid_argument(
"Bad filename for JSON");
345 Json::Value prevScores = root.get(
"scores", Json::nullValue);
347 Json::Value subScores;
348 subScores[
"distance"] = scores[0];
349 subScores[
"energy"] = totalEnergySpent;
351 prevScores.append(subScores);
352 root[
"scores"] = prevScores;
355 payloadLog.open(controlFilename.c_str(),ofstream::out);
357 payloadLog << root << std::endl;
362 for(
size_t i = 0; i < m_allControllers.size(); i++)
364 delete m_allControllers[i];
366 m_allControllers.clear();
369 const double JSONQuadCPGControl::getCPGValue(std::size_t i)
const
372 return (*m_pCPGSys)[i];
375 double JSONQuadCPGControl::getScore()
const
377 if (scores.size() == 2)
383 throw std::runtime_error(
"Called before scores were obtained!");
389 (Json::Value edgeParam)
391 assert(edgeParam[0].size() == 2);
393 double lowerLimit = m_config.lowPhase;
394 double upperLimit = m_config.highPhase;
395 double range = upperLimit - lowerLimit;
397 array_4D actionList(boost::extents[m_config.segmentSpan]
398 [m_config.theirMuscles]
399 [m_config.ourMuscles]
413 Json::Value::iterator edgeIt = edgeParam.end();
417 while (i < m_config.segmentSpan)
419 while(j < m_config.theirMuscles)
421 while(k < m_config.ourMuscles)
423 if (edgeIt == edgeParam.begin())
425 std::cout <<
"ran out before table populated!"
432 if (i == 1 && j == k)
440 Json::Value edgeParam = *edgeIt;
441 assert(edgeParam.size() == 2);
443 actionList[i][j][k][0] = edgeParam[0].asDouble();
446 actionList[i][j][k][1] = edgeParam[1].asDouble() *
447 (range) + lowerLimit;
463 std::cout<<
"Params used: " << count << std::endl;
465 assert(edgeParam.begin() == edgeIt);
469 array_2D JSONQuadCPGControl::scaleNodeActions
470 (Json::Value actions)
472 std::size_t numControllers = actions.size();
473 std::size_t numActions = actions[0].size();
475 array_2D nodeActions(boost::extents[numControllers][numActions]);
477 array_2D limits(boost::extents[2][numActions]);
480 assert(numActions == 2);
482 limits[0][0] = m_config.lowFreq;
483 limits[1][0] = m_config.highFreq;
484 limits[0][1] = m_config.lowAmp;
485 limits[1][1] = m_config.highAmp;
487 Json::Value::iterator nodeIt = actions.begin();
490 for( std::size_t i = 0; i < numControllers; i++)
492 Json::Value nodeParam = *nodeIt;
493 for( std::size_t j = 0; j < numActions; j++)
495 nodeActions[i][j] = ( (nodeParam.get(j, 0.0)).asDouble() *
496 (limits[1][j] - limits[0][j])) + limits[0][j];
Contains the definition of class ImpedanceControl. $Id$.
virtual void onStep(BaseQuadModelLearning &subject, double dt)
virtual void onSetup(BaseQuadModelLearning &subject)
void update(std::vector< double > &descCom, double dt)
std::deque< double > tensionHistory
void setConnectivity(const std::vector< tgCPGActuatorControl * > &allStrings, array_4D edgeParams)
std::deque< double > restLengths
JSONQuadCPGControl(JSONQuadCPGControl::Config config, std::string args, std::string resourcePath="")
Definition of the tgCPGStringControl observer class.
Contains the definition of abstract base class tgSpringCableActuator. Assumes that the string is line...
A series of functions to assist with file input/output.
static std::string getResourcePath(std::string relPath)
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)
virtual void onTeardown(BaseQuadModelLearning &subject)
A controller for the template class BaseSpineModelLearning.
Definition of class CPGEquations.
virtual void onStep(tgModel &model, double dt)
virtual void setupCPGs(BaseQuadModelLearning &subject, array_2D nodeActions, array_4D edgeActions)
Definition of class CPGNode.
virtual array_4D scaleEdgeActions(Json::Value edgeParam)
virtual void onSetup(tgModel &model)
void notifyStep(double dt)