38 #include "examples/learningSpines/tgCPGCableControl.h"
48 #include <json/json.h>
77 segmentNumber(segnum),
93 throw std::invalid_argument(
"segmentSpan parameter is negative.");
97 throw std::invalid_argument(
"theirMuscles parameter is negative.");
101 throw std::invalid_argument(
"Our Muscles parameter is negative.");
105 throw std::invalid_argument(
"Edge parameters is negative.");
109 throw std::invalid_argument(
"Segment number is negative.");
113 throw std::invalid_argument(
"control time is negative.");
117 throw std::invalid_argument(
"impedance control tension is negative.");
121 throw std::invalid_argument(
"impedance control position is negative.");
125 throw std::invalid_argument(
"impedance control velocity is negative.");
129 throw std::invalid_argument(
"Control Length is negative.");
140 std::string resourcePath) :
143 m_dataObserver(
"logs/TCData"),
147 if (resourcePath !=
"")
153 controlFilePath =
"";
156 controlFilename = controlFilePath + args;
159 JSONCPGControl::~JSONCPGControl()
173 bool parsingSuccessful = reader.parse( FileHelpers::getFileString(controlFilename.c_str()), root );
174 if ( !parsingSuccessful )
177 std::cout <<
"Failed to parse configuration\n"
178 << reader.getFormattedErrorMessages();
179 throw std::invalid_argument(
"Bad filename for JSON");
183 Json::Value nodeVals = root.get(
"nodeVals",
"UTF-8");
184 Json::Value edgeVals = root.get(
"edgeVals",
"UTF-8");
186 nodeVals = nodeVals.get(
"params",
"UTF-8");
187 edgeVals = edgeVals.get(
"params",
"UTF-8");
190 array_2D nodeParams = scaleNodeActions(nodeVals);
192 setupCPGs(subject, nodeParams, edgeParams);
194 initConditions = subject.getSegmentCOM(m_config.segmentNumber);
195 #ifdef LOGGING // Conditional compile for data logging
196 m_dataObserver.
onSetup(subject);
199 #if (0) // Conditional Compile for debug info
200 std::cout << *m_pCPGSys << std::endl;
209 std::vector <tgSpringCableActuator*> allMuscles = subject.getAllMuscles();
211 for (std::size_t i = 0; i < allMuscles.size(); i++)
218 #endif // Update for kinematic cables
219 allMuscles[i]->attach(pStringControl);
221 m_allControllers.push_back(pStringControl);
226 for (std::size_t i = 0; i < m_allControllers.size(); i++)
228 m_allControllers[i]->assignNodeNumber(*m_pCPGSys, nodeActions);
232 for (std::size_t i = 0; i < m_allControllers.size(); i++)
235 assert(pStringInfo != NULL);
242 if (m_config.useDefault)
244 pStringInfo->setupControl(*p_ipc);
248 pStringInfo->setupControl(*p_ipc, m_config.controlLength);
257 if (m_updateTime >= m_config.controlTime)
259 std::size_t numControllers = subject.getNumberofMuslces();
261 double descendingCommand = 2.0;
262 std::vector<double> desComs (numControllers, descendingCommand);
264 m_pCPGSys->
update(desComs, m_updateTime);
265 #ifdef LOGGING // Conditional compile for data logging
266 m_dataObserver.
onStep(subject, m_updateTime);
272 double currentHeight = subject.getSegmentCOM(m_config.segmentNumber)[1];
275 if (currentHeight > 25 || currentHeight < 1.0)
287 std::vector<double> finalConditions = subject.getSegmentCOM(m_config.segmentNumber);
289 const double newX = finalConditions[0];
290 const double newZ = finalConditions[2];
291 const double oldX = initConditions[0];
292 const double oldZ = initConditions[2];
294 const double distanceMoved = sqrt((newX-oldX) * (newX-oldX) +
295 (newZ-oldZ) * (newZ-oldZ));
299 scores.push_back(-1.0);
303 scores.push_back(distanceMoved);
308 double totalEnergySpent=0;
310 std::vector<tgSpringCableActuator* > tmpStrings = subject.getAllMuscles();
312 for(std::size_t i=0; i<tmpStrings.size(); i++)
319 const double previousLength = stringHist.
restLengths[j-1];
320 const double currentLength = stringHist.
restLengths[j];
322 double motorSpeed = (currentLength-previousLength);
325 const double workDone = previousTension * motorSpeed;
326 totalEnergySpent += workDone;
330 scores.push_back(totalEnergySpent);
332 std::cout <<
"Dist travelled " << scores[0] << std::endl;
337 bool parsingSuccessful = reader.parse( FileHelpers::getFileString(controlFilename.c_str()), root );
338 if ( !parsingSuccessful )
341 std::cout <<
"Failed to parse configuration\n"
342 << reader.getFormattedErrorMessages();
343 throw std::invalid_argument(
"Bad filename for JSON");
346 Json::Value prevScores = root.get(
"scores", Json::nullValue);
348 Json::Value subScores;
349 subScores[
"distance"] = scores[0];
350 subScores[
"energy"] = totalEnergySpent;
352 prevScores.append(subScores);
353 root[
"scores"] = prevScores;
356 payloadLog.open(controlFilename.c_str(),ofstream::out);
358 payloadLog << root << std::endl;
363 for(
size_t i = 0; i < m_allControllers.size(); i++)
365 delete m_allControllers[i];
367 m_allControllers.clear();
370 const double JSONCPGControl::getCPGValue(std::size_t i)
const
373 return (*m_pCPGSys)[i];
376 double JSONCPGControl::getScore()
const
378 if (scores.size() == 2)
384 throw std::runtime_error(
"Called before scores were obtained!");
390 (Json::Value edgeParam)
392 assert(edgeParam[0].size() == 2);
394 double lowerLimit = m_config.lowPhase;
395 double upperLimit = m_config.highPhase;
396 double range = upperLimit - lowerLimit;
398 array_4D actionList(boost::extents[m_config.segmentSpan]
399 [m_config.theirMuscles]
400 [m_config.ourMuscles]
414 Json::Value::iterator edgeIt = edgeParam.end();
418 while (i < m_config.segmentSpan)
420 while(j < m_config.theirMuscles)
422 while(k < m_config.ourMuscles)
424 if (edgeIt == edgeParam.begin())
426 std::cout <<
"ran out before table populated!"
433 if (i == 1 && j == k)
441 Json::Value edgeParam = *edgeIt;
442 assert(edgeParam.size() == 2);
444 actionList[i][j][k][0] = edgeParam[0].asDouble();
447 actionList[i][j][k][1] = edgeParam[1].asDouble() *
448 (range) + lowerLimit;
464 std::cout<<
"Params used: " << count << std::endl;
466 assert(edgeParam.begin() == edgeIt);
470 array_2D JSONCPGControl::scaleNodeActions
471 (Json::Value actions)
473 std::size_t numControllers = actions.size();
474 std::size_t numActions = actions[0].size();
476 array_2D nodeActions(boost::extents[numControllers][numActions]);
478 array_2D limits(boost::extents[2][numActions]);
481 assert(numActions == 2);
483 limits[0][0] = m_config.lowFreq;
484 limits[1][0] = m_config.highFreq;
485 limits[0][1] = m_config.lowAmp;
486 limits[1][1] = m_config.highAmp;
488 Json::Value::iterator nodeIt = actions.begin();
491 for( std::size_t i = 0; i < numControllers; i++)
493 Json::Value nodeParam = *nodeIt;
494 for( std::size_t j = 0; j < numActions; j++)
496 nodeActions[i][j] = ( (nodeParam.get(j, 0.0)).asDouble() *
497 (limits[1][j] - limits[0][j])) + limits[0][j];
Contains the definition of class ImpedanceControl. $Id$.
virtual void onStep(BaseSpineModelLearning &subject, double dt)
void update(std::vector< double > &descCom, double dt)
std::deque< double > tensionHistory
virtual array_4D scaleEdgeActions(Json::Value edgeParam)
void setConnectivity(const std::vector< tgCPGActuatorControl * > &allStrings, array_4D edgeParams)
std::deque< double > restLengths
An adaptation of JSONCPGControl that utilizes JSON for parameters.
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)
Definition of the tgCPGStringControl observer class.
A template base class for a tensegrity spine.
Contains the definition of abstract base class tgSpringCableActuator. Assumes that the string is line...
A series of functions to assist with file input/output.
virtual void onTeardown(BaseSpineModelLearning &subject)
static std::string getResourcePath(std::string relPath)
virtual void setupCPGs(BaseSpineModelLearning &subject, array_2D nodeActions, array_4D edgeActions)
A controller for the template class BaseSpineModelLearning.
Definition of class CPGEquations.
JSONCPGControl(JSONCPGControl::Config config, std::string args, std::string resourcePath="")
virtual void onStep(tgModel &model, double dt)
Definition of class CPGNode.
virtual void onSetup(tgModel &model)
virtual void onSetup(BaseSpineModelLearning &subject)
void notifyStep(double dt)