37 #include "examples/learningSpines/tgCPGCableControl.h"
38 #include "examples/learningSpines/tgSCASineControl.h"
45 #include "examples/learningSpines/tgCPGCableControl.h"
47 #include "neuralNet/Neural Network v2/neuralNetwork.h"
49 #include <json/json.h>
67 std::string resourcePath) :
74 JSONGoalTension::~JSONGoalTension()
85 bool parsingSuccessful = reader.parse( FileHelpers::getFileString(controlFilename.c_str()), root );
86 if ( !parsingSuccessful )
89 std::cout <<
"Failed to parse configuration\n"
90 << reader.getFormattedErrorMessages();
91 throw std::invalid_argument(
"Bad filename for JSON");
95 Json::Value nodeVals = root.get(
"nodeVals",
"UTF-8");
96 Json::Value edgeVals = root.get(
"edgeVals",
"UTF-8");
98 nodeVals = nodeVals.get(
"params",
"UTF-8");
99 edgeVals = edgeVals.get(
"params",
"UTF-8");
102 array_2D nodeParams = scaleNodeActions(nodeVals);
104 setupCPGs(subject, nodeParams, edgeParams);
106 Json::Value feedbackParams = root.get(
"feedbackVals",
"UTF-8");
107 feedbackParams = feedbackParams.get(
"params",
"UTF-8");
110 m_config.numStates = feedbackParams.get(
"numStates",
"UTF-8").asInt();
111 m_config.numActions = feedbackParams.get(
"numActions",
"UTF-8").asInt();
112 m_config.numHidden = feedbackParams.get(
"numHidden",
"UTF-8").asInt();
114 feedbackWeights.resize(boost::extents[m_config.numActions][m_config.numStates]);
117 Json::Value goalParams = root.get(
"goalVals",
"UTF-8");
118 goalParams = goalParams.get(
"params",
"UTF-8");
121 m_config.goalStates = goalParams.get(
"numStates",
"UTF-8").asInt();
122 m_config.goalActions = goalParams.get(
"numActions",
"UTF-8").asInt();
123 m_config.goalHidden = goalParams.get(
"numHidden",
"UTF-8").asInt();
125 std::string nnFile_goal = controlFilePath + goalParams.get(
"neuralFilename",
"UTF-8").asString();
127 nn_goal =
new neuralNetwork(m_config.goalStates, m_config.goalHidden, m_config.goalActions);
129 nn_goal->loadWeights(nnFile_goal.c_str());
131 initConditions = subject.getSegmentCOM(m_config.segmentNumber);
132 #ifdef LOGGING // Conditional compile for data logging
133 m_dataObserver.
onSetup(subject);
136 #if (0) // Conditional Compile for debug info
137 std::cout << *m_pCPGSys << std::endl;
146 if (m_updateTime >= m_config.controlTime)
148 #if (1) // Goal and cable
150 std::vector<double> desComs = getFeedback(subject);
152 const BaseSpineModelGoal* goalSubject = tgCast::cast<BaseSpineModelLearning, BaseSpineModelGoal>(subject);
157 std::size_t numControllers = subject.getNumberofMuslces() * 3;
159 double descendingCommand = 0.0;
160 std::vector<double> desComs (numControllers, descendingCommand);
164 m_pCPGSys->
update(desComs, m_updateTime);
166 catch (std::runtime_error& e)
173 #ifdef LOGGING // Conditional compile for data logging
174 m_dataObserver.
onStep(subject, m_updateTime);
180 double currentHeight = subject.getSegmentCOM(m_config.segmentNumber)[1];
183 if (currentHeight > 25 || currentHeight < 1.0)
187 throw std::runtime_error(
"Height out of range");
196 std::vector<double> finalConditions = subject.getSegmentCOM(m_config.segmentNumber);
198 const double newX = finalConditions[0];
199 const double newZ = finalConditions[2];
200 const double oldX = initConditions[0];
201 const double oldZ = initConditions[2];
203 const BaseSpineModelGoal* goalSubject = tgCast::cast<BaseSpineModelLearning, BaseSpineModelGoal>(subject);
205 const double distanceMoved = calculateDistanceMoved(goalSubject);
209 scores.push_back(-1.0);
213 scores.push_back(distanceMoved);
218 double totalEnergySpent=0;
220 std::vector<tgSpringCableActuator* > tmpStrings = subject.getAllMuscles();
222 for(std::size_t i=0; i<tmpStrings.size(); i++)
229 const double previousLength = stringHist.
restLengths[j-1];
230 const double currentLength = stringHist.
restLengths[j];
232 double motorSpeed = (currentLength-previousLength);
235 const double workDone = previousTension * motorSpeed;
236 totalEnergySpent += workDone;
240 scores.push_back(totalEnergySpent);
242 std::cout <<
"Dist travelled " << scores[0] << std::endl;
247 bool parsingSuccessful = reader.parse( FileHelpers::getFileString(controlFilename.c_str()), root );
248 if ( !parsingSuccessful )
251 std::cout <<
"Failed to parse configuration\n"
252 << reader.getFormattedErrorMessages();
253 throw std::invalid_argument(
"Bad filename for JSON");
256 Json::Value prevScores = root.get(
"scores", Json::nullValue);
258 Json::Value subScores;
259 subScores[
"distance"] = scores[0];
260 subScores[
"energy"] = totalEnergySpent;
262 prevScores.append(subScores);
263 root[
"scores"] = prevScores;
266 payloadLog.open(controlFilename.c_str(),ofstream::out);
268 payloadLog << root << std::endl;
273 for(
size_t i = 0; i < m_allControllers.size(); i++)
275 delete m_allControllers[i];
277 m_allControllers.clear();
282 array_2D JSONGoalTension::scaleNodeActions (Json::Value actions)
284 std::size_t numControllers = actions.size();
285 std::size_t numActions = actions[0].size();
287 array_2D nodeActions(boost::extents[numControllers][numActions]);
289 array_2D limits(boost::extents[2][numActions]);
292 assert(numActions >= 5);
294 limits[0][0] = m_config.lowFreq;
295 limits[1][0] = m_config.highFreq;
296 limits[0][1] = m_config.lowAmp;
297 limits[1][1] = m_config.highAmp;
298 limits[0][2] = m_config.freqFeedbackMin;
299 limits[1][2] = m_config.freqFeedbackMax;
300 limits[0][3] = m_config.ampFeedbackMin;
301 limits[1][3] = m_config.ampFeedbackMax;
302 limits[0][4] = m_config.phaseFeedbackMin;
303 limits[1][4] = m_config.phaseFeedbackMax;
305 for (std::size_t i = 5; i < numActions; i++)
311 Json::Value::iterator nodeIt = actions.begin();
314 for( std::size_t i = 0; i < numControllers; i++)
316 Json::Value nodeParam = *nodeIt;
317 for( std::size_t j = 0; j < numActions; j++)
319 nodeActions[i][j] = ( (nodeParam.get(j, 0.0)).asDouble() *
320 (limits[1][j] - limits[0][j])) + limits[0][j];
330 const int nSeg = subject->getSegments() - 1;
336 const btVector3 currentPosVector = subject->getSegmentCOMVector(m_config.segmentNumber);
338 const btVector3 goalPosition = subject->goalBoxPosition();
340 btVector3 desiredHeading = (goalPosition - currentPosVector).normalize();
344 const btVector3 firstSegment = subject->getSegmentCOMVector(0);
345 const btVector3 secondSegment = subject->getSegmentCOMVector(1);
347 btVector3 currentHeading = (firstSegment - secondSegment).normalize();
349 std::vector<double> state;
350 state.push_back(desiredHeading.getX());
351 state.push_back(desiredHeading.getZ());
352 state.push_back(currentHeading.getX());
353 state.push_back(currentHeading.getZ());
355 double *inputs =
new double[m_config.goalStates];
356 for (std::size_t i = 0; i < state.size(); i++)
358 assert(state[i] >= -1.0 && state[i] <= 1.0);
363 double *output = nn_goal->feedForwardPattern(inputs);
365 vector<double> actions;
368 for(
int j=0;j<m_config.goalActions;j++)
370 std::cout << output[j] <<
" ";
372 std::cout << std::endl;
375 for(
int j=0;j<m_config.goalActions;j++)
377 actions.push_back(output[j]);
380 transformFeedbackActions(actions);
382 assert(m_config.goalActions * nSeg == m_allControllers.size());
385 for (
int i = 0; i != nSeg; i++)
387 for(
int j=0;j<m_config.goalActions;j++)
389 m_allControllers[i * m_config.goalActions + j]->updateTensionSetpoint(actions[j] * m_config.tensFeedback + m_config.tensFeedback);
401 std::vector<double> feedback;
403 const std::vector<tgSpringCableActuator*>& allCables = subject.getAllMuscles();
406 std::size_t n = allCables.size();
407 for(std::size_t i = 0; i != n; i++)
410 std::vector<double > state = getCableState(cable);
412 vector<double> actions;
413 for(
int j=0;j<m_config.numActions;j++)
416 actions.push_back(state[0] * feedbackWeights[j][0] + state[1] * feedbackWeights[j][1]);
419 transformFeedbackActions(actions);
421 feedback.insert(feedback.end(), actions.begin(), actions.end());
433 for(
int i = 0; i < m_config.numActions; i++)
435 for(
int j = 0; j < m_config.numStates; j++)
437 feedbackWeights[i][j] = nodeVals[0][k];
Contains the definition of class ImpedanceControl. $Id$.
void update(std::vector< double > &descCom, double dt)
A controller for the template class BaseSpineModelLearning.
std::deque< double > tensionHistory
virtual array_4D scaleEdgeActions(Json::Value edgeParam)
std::deque< double > restLengths
Definition of the tgCPGStringControl observer class.
Implementing the tetrahedral complex spine inspired by Tom Flemons.
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)
Contains the definition of class tgBasicActuator.
virtual void setupFeedbackWeights(array_2D nodeVals)
virtual std::vector< double > getGoalFeedback(const BaseSpineModelGoal *subject)
virtual void onStep(tgModel &model, double dt)
JSONGoalTension(JSONGoalControl::Config config, std::string args, std::string resourcePath="")
Definition of class CPGEquationsFB.
virtual void onSetup(tgModel &model)
virtual void onSetup(BaseSpineModelLearning &subject)
virtual void onStep(BaseSpineModelLearning &subject, double dt)
void notifyStep(double dt)