39 #include "tgCPGCableControl.h"
78 lp, hp, kt, kp, kv, def, cl, lf, hf),
79 freqFeedbackMin(ffMin),
80 freqFeedbackMax(ffMax),
81 ampFeedbackMin(afMin),
82 ampFeedbackMax(afMax),
83 phaseFeedbackMin(pfMin),
84 phaseFeedbackMax(pfMax)
95 std::string resourcePath,
101 feedbackConfigFilename(fc),
103 feedbackEvolution(args +
"_fb", fc, resourcePath),
105 feedbackLearning(false)
108 if (resourcePath !=
"")
110 path = FileHelpers::getResourcePath(resourcePath);
117 feedbackConfigData.readFile(path + feedbackConfigFilename);
118 feedbackLearning = feedbackConfigData.getintvalue(
"learning");
132 feedbackAdapter.
initialize(&feedbackEvolution,
139 std::vector<double> state;
143 array_2D nodeParams = scaleNodeActions(nodeAdapter.step(dt, state));
145 setupCPGs(subject, nodeParams, edgeParams);
147 initConditions = subject.getSegmentCOM(m_config.segmentNumber);
148 #ifdef LOGGING // Conditional compile for data logging
149 m_dataObserver.
onSetup(subject);
152 #if (0) // Conditional Compile for debug info
153 std::cout << *m_pCPGSys << std::endl;
162 if (m_updateTime >= m_config.controlTime)
165 std::vector<double> desComs = getFeedback(subject);
168 std::size_t numControllers = subject.getNumberofMuslces() * 3;
170 double descendingCommand = 0.0;
171 std::vector<double> desComs (numControllers, descendingCommand);
175 m_pCPGSys->
update(desComs, m_updateTime);
177 catch (std::runtime_error& e)
184 #ifdef LOGGING // Conditional compile for data logging
185 m_dataObserver.
onStep(subject, m_updateTime);
191 double currentHeight = subject.getSegmentCOM(m_config.segmentNumber)[1];
194 if (currentHeight > 25 || currentHeight < 1.0)
198 throw std::runtime_error(
"Height out of range");
207 std::vector<double> finalConditions = subject.getSegmentCOM(m_config.segmentNumber);
209 const double newX = finalConditions[0];
210 const double newZ = finalConditions[2];
211 const double oldX = initConditions[0];
212 const double oldZ = initConditions[2];
214 const double distanceMoved = sqrt((newX-oldX) * (newX-oldX) +
215 (newZ-oldZ) * (newZ-oldZ));
219 scores.push_back(-1.0);
223 scores.push_back(distanceMoved);
228 double totalEnergySpent=0;
230 std::vector<tgSpringCableActuator* > tmpStrings = subject.getAllMuscles();
232 for(
int i=0; i<tmpStrings.size(); i++)
239 const double previousLength = stringHist.
restLengths[j-1];
240 const double currentLength = stringHist.
restLengths[j];
242 double motorSpeed = (currentLength-previousLength);
245 const double workDone = previousTension * motorSpeed;
246 totalEnergySpent += workDone;
250 scores.push_back(totalEnergySpent);
252 edgeAdapter.endEpisode(scores);
253 nodeAdapter.endEpisode(scores);
254 feedbackAdapter.endEpisode(scores);
259 for(
size_t i = 0; i < m_allControllers.size(); i++)
261 delete m_allControllers[i];
263 m_allControllers.clear();
266 void SpineFeedbackControl::setupCPGs(
BaseSpineModelLearning& subject, array_2D nodeActions, array_4D edgeActions)
269 std::vector <tgSpringCableActuator*> allMuscles = subject.getAllMuscles();
271 CPGEquationsFB& m_CPGFBSys = *(tgCast::cast<CPGEquations, CPGEquationsFB>(m_pCPGSys));
273 for (std::size_t i = 0; i < allMuscles.size(); i++)
279 allMuscles[i]->attach(pStringControl);
284 m_allControllers.push_back(pStringControl);
288 for (std::size_t i = 0; i < m_allControllers.size(); i++)
291 assert(pStringInfo != NULL);
298 if (m_config.useDefault)
300 pStringInfo->setupControl(*p_ipc);
304 pStringInfo->setupControl(*p_ipc, m_config.controlLength);
310 array_2D SpineFeedbackControl::scaleNodeActions
311 (vector< vector <double> > actions)
313 std::size_t numControllers = nodeConfigData.getintvalue(
"numberOfControllers");
314 std::size_t numActions = nodeConfigData.getintvalue(
"numberOfActions");
316 assert( actions.size() == numControllers);
317 assert( actions[0].size() == numActions);
319 array_2D nodeActions(boost::extents[numControllers][numActions]);
321 array_2D limits(boost::extents[2][numActions]);
324 assert(numActions == 5);
326 limits[0][0] = m_config.lowFreq;
327 limits[1][0] = m_config.highFreq;
328 limits[0][1] = m_config.lowAmp;
329 limits[1][1] = m_config.highAmp;
330 limits[0][2] = m_config.freqFeedbackMin;
331 limits[1][2] = m_config.freqFeedbackMax;
332 limits[0][3] = m_config.ampFeedbackMin;
333 limits[1][3] = m_config.ampFeedbackMax;
334 limits[0][4] = m_config.phaseFeedbackMin;
335 limits[1][4] = m_config.phaseFeedbackMax;
338 for( std::size_t i = 0; i < numControllers; i++)
340 for( std::size_t j = 0; j < numActions; j++)
342 nodeActions[i][j] = ( actions[i][j] *
343 (limits[1][j] - limits[0][j])) + limits[0][j];
353 std:vector<double> feedback;
357 const std::vector<tgSpringCableActuator*>& allCables = subject.getAllMuscles();
359 std::size_t n = allCables.size();
360 for(std::size_t i = 0; i != n; i++)
363 std::vector<double > state = getCableState(cable);
364 std::vector< std::vector<double> > actions = feedbackAdapter.step(m_updateTime, state);
365 std::vector<double> cableFeedback = transformFeedbackActions(actions);
367 feedback.insert(feedback.end(), cableFeedback.begin(), cableFeedback.end());
378 std::vector<double> state;
384 const double maxTension = cable.
getConfig().maxTens;
385 state.push_back((cable.
getTension() - maxTension / 2.0) / maxTension);
390 std::vector<double> SpineFeedbackControl::transformFeedbackActions(std::vector< std::vector<double> >& actions)
393 std:vector<double> feedback;
395 std::size_t numControllers = feedbackConfigData.getintvalue(
"numberOfControllers");
396 std::size_t numActions = feedbackConfigData.getintvalue(
"numberOfActions");
398 assert( actions.size() == numControllers);
399 assert( actions[0].size() == numActions);
402 for( std::size_t i = 0; i < numControllers; i++)
404 for( std::size_t j = 0; j < numActions; j++)
406 feedback.push_back(actions[i][j] * 2.0 - 1.0);
Contains the definition of class ImpedanceControl. $Id$.
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)
void initialize(NeuroEvolution *evo, bool isLearning, configuration config)
A controller for the template class BaseSpineModelLearning.
void update(std::vector< double > &descCom, double dt)
std::deque< double > tensionHistory
virtual const double getTension() const
virtual const double getStartLength() const
virtual void onStep(BaseSpineModelLearning &subject, double dt)
SpineFeedbackControl(SpineFeedbackControl::Config config, std::string args, std::string resourcePath="", std::string ec="edgeConfig.ini", std::string nc="nodeConfig.ini", std::string fc="feedbackConfig.ini")
void setConnectivity(const std::vector< tgCPGActuatorControl * > &allStrings, array_4D edgeParams)
std::deque< double > restLengths
Definition of the tgCPGStringControl observer class.
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.
Definition of class CPGNodeFB.
Contains the definition of class AnnealEvolution. Adapting NeuroEvolution to do Simulated Annealing...
Contains the definition of class tgBasicActuator.
const Config & getConfig() const
virtual array_4D scaleEdgeActions(std::vector< std::vector< double > > actions)
virtual void onStep(tgModel &model, double dt)
Definition of class CPGEquationsFB.
void initialize(AnnealEvolution *evo, bool isLearning, configuration config)
virtual void onSetup(tgModel &model)
virtual void onSetup(BaseSpineModelLearning &subject)
virtual const double getCurrentLength() const
void notifyStep(double dt)
void assignNodeNumberFB(CPGEquationsFB &CPGSys, array_2D nodeParams)
virtual void onTeardown(BaseSpineModelLearning &subject)