28 #include "Escape_T6Controller.h"
46 # define M_PI 3.14159265358979323846
50 Escape_T6Controller::Escape_T6Controller(
const double initialLength,
52 std::string resourcePath,
54 m_initialLengths(initialLength),
56 maxStringLengthFactor(0.50),
60 configPath(resourcePath),
63 clusters.resize(nClusters);
64 for (
int i=0; i<nClusters; i++) {
65 clusters[i].resize(musclesPerCluster);
76 const std::vector<tgBasicActuator*> muscles = subject.
getAllMuscles();
77 for (
size_t i = 0; i < muscles.size(); ++i) {
79 assert(pMuscle != NULL);
83 populateClusters(subject);
86 initializeSineWaves();
88 std::vector<double> state;
91 actions = evolutionAdapter.step(dt,state);
104 throw std::invalid_argument(
"dt is not positive");
108 setPreferredMuscleLengths(subject, dt);
109 const std::vector<tgBasicActuator*> muscles = subject.
getAllMuscles();
112 for (
size_t i = 0; i < muscles.size(); ++i) {
114 assert(pMuscle != NULL);
118 for(
size_t i=0; i<muscles.size(); i++) {
119 std::vector<double> tmp;
120 for(
int j=0;j<2;j++) {
123 actions.push_back(tmp);
142 std::vector<double> scores;
143 double distance = displacement(subject);
144 double energySpent = totalEnergySpent(subject);
147 scores.push_back(distance);
148 scores.push_back(energySpent);
150 std::cout <<
"Tearing down" << std::endl;
151 evolutionAdapter.endEpisode(scores);
164 bool usingManualParams =
false;
165 std::vector <double> manualParams(4 * nClusters, 1);
166 if (usingManualParams) {
167 std::cout <<
"Using manually set parameters\n";
168 std::string filename =
"logs/Jan242015/params.dat";
170 manualParams = readManualParams(lineNumber, filename);
173 double pretension = 0.90;
175 double mins[4] = {m_initialLengths * (pretension - maxStringLengthFactor),
181 double maxes[4] = {m_initialLengths * (pretension + maxStringLengthFactor),
185 double ranges[4] = {maxes[0]-mins[0], maxes[1]-mins[1], maxes[2]-mins[2], maxes[3]-mins[3]};
187 for(
size_t i=0;i<actions.size();i++) {
188 for (
size_t j=0; j<actions[i].size(); j++) {
189 if (usingManualParams) {
190 actions[i][j] = manualParams[i*actions[i].size() + j]*(ranges[j])+mins[j];
192 actions[i][j] = actions[i][j]*(ranges[j])+mins[j];
203 assert(actions.size() == clusters.size());
206 for (
size_t cluster = 0; cluster < clusters.size(); cluster++) {
207 amplitude[cluster] = actions[cluster][0];
208 angularFrequency[cluster] = actions[cluster][1];
209 phaseChange[cluster] = actions[cluster][2];
210 dcOffset[cluster] = actions[cluster][3];
211 dcOffset[cluster] = 1;
216 void Escape_T6Controller::setupAdapter() {
220 if (configPath !=
"") {
227 std::string configAnnealEvolution = path + configName;
229 bool isLearning =
true;
231 configEvolutionAdapter.readFile(configAnnealEvolution);
233 evolutionAdapter.
initialize(evo, isLearning, configEvolutionAdapter);
236 double Escape_T6Controller::totalEnergySpent(
Escape_T6Model& subject) {
237 double totalEnergySpent=0;
239 std::vector<tgBasicActuator* > tmpStrings = subject.
getAllMuscles();
240 for(
size_t i=0; i<tmpStrings.size(); i++) {
245 const double previousLength = stringHist.
restLengths[j-1];
246 const double currentLength = stringHist.
restLengths[j];
248 double motorSpeed = (currentLength-previousLength);
251 const double workDone = previousTension * motorSpeed;
252 totalEnergySpent += workDone;
255 return totalEnergySpent;
260 void Escape_T6Controller::setPreferredMuscleLengths(
Escape_T6Model& subject,
double dt) {
267 for(
int iMuscle=0; iMuscle < nMuscles; iMuscle++) {
269 const std::vector<tgBasicActuator*> muscles = subject.
getAllMuscles();
272 assert(pMuscle != NULL);
275 oldCluster = cluster;
278 }
else if (iMuscle < 8) {
280 }
else if (iMuscle < 12) {
282 }
else if (iMuscle < 16 ) {
284 }
else if (iMuscle < 18) {
286 }
else if (iMuscle < 20) {
288 }
else if (iMuscle < 22) {
294 double newLength = amplitude[cluster] * sin(angularFrequency[cluster] * m_totalTime + phase) + dcOffset[cluster];
295 double minLength = m_initialLengths * (1-maxStringLengthFactor);
296 double maxLength = m_initialLengths * (1+maxStringLengthFactor);
297 if (newLength <= minLength) {
298 newLength = minLength;
299 }
else if (newLength >= maxLength) {
300 newLength = maxLength;
303 if (oldCluster != cluster) {
304 phase += phaseChange[cluster];
309 void Escape_T6Controller::populateClusters(
Escape_T6Model& subject) {
310 for(
int cluster=0; cluster < nClusters; cluster++) {
311 std::ostringstream ss;
313 std::string suffix = ss.str();
314 std::vector <tgBasicActuator*> musclesInThisCluster = subject.
find<
tgBasicActuator>(
"muscle cluster" + suffix);
315 clusters[cluster] = std::vector<tgBasicActuator*>(musclesInThisCluster);
319 void Escape_T6Controller::initializeSineWaves() {
320 amplitude =
new double[nClusters];
321 angularFrequency =
new double[nClusters];
322 phaseChange =
new double[nClusters];
323 dcOffset =
new double[nClusters];
326 double Escape_T6Controller::displacement(
Escape_T6Model& subject) {
327 std::vector<double> finalPosition = subject.
getBallCOM();
332 const double newX = finalPosition[0];
333 const double newZ = finalPosition[2];
334 const double oldX = initPosition[0];
335 const double oldZ = initPosition[2];
337 const double distanceMoved = sqrt((newX-oldX) * (newX-oldX) +
338 (newZ-oldZ) * (newZ-oldZ));
339 return distanceMoved;
342 std::vector<double> Escape_T6Controller::readManualParams(
int lineNumber, std::string filename) {
343 assert(lineNumber > 0);
344 std::vector<double> result(32, 1.0);
346 std::ifstream infile(filename.c_str(), std::ifstream::in);
349 if (infile.is_open()) {
350 std::cout <<
"OPENED FILE\n";
351 for (
int i=0; i<lineNumber; i++) {
352 getline(infile, line);
356 std::cerr <<
"ERROR: Manual Parameters file not found\n";
363 std::stringstream lineStream(line);
366 while(getline(lineStream,cell,
',')) {
367 result[iCell] = atof(cell.c_str());
371 bool tweaking =
false;
374 for (
size_t i=0; i < result.size(); i++) {
375 std::cout<<
"Entered Cell " << i <<
": " << result[i] <<
"\n";
376 double seed = ((double) (rand() % 100)) / 100;
377 result[i] += (0.01 * seed) - 0.005;
381 std::cerr <<
"WARNING: Input parameters are manually set and constant. Expect the same results each iteration.\n";
387 std::vector<double> currentPosition = subject.
getBallCOM();
388 std::cout << currentPosition[0]/10 <<
" " << currentPosition[1]/10 <<
" " << currentPosition[2]/10 <<
" ";
389 std::cout << std::endl;
393 void Escape_T6Controller::printMuscleTensions(
Escape_T6Model& subject) {
394 const std::vector<tgBasicActuator*> muscles = subject.
getAllMuscles();
395 for(
size_t i=0; i<muscles.size(); i++) {
396 std::cout << (muscles[i]->getTension())/10 <<
" ";
401 void Escape_T6Controller::printMuscleLengths(
Escape_T6Model& subject) {
402 const std::vector<tgBasicActuator*> muscles = subject.
getAllMuscles();
403 for(
size_t i=0; i<muscles.size(); i++) {
404 std::cout << (muscles[i]->getCurrentLength())/10 <<
" ";
409 void Escape_T6Controller::printSineParams() {
410 for (
size_t cluster = 0; cluster < clusters.size(); cluster++) {
411 std::cout <<
"amplitude[" << cluster <<
"]: " << amplitude[cluster] << std::endl;
412 std::cout <<
"angularFrequency[" << cluster <<
"]: " << angularFrequency[cluster] << std::endl;
413 std::cout <<
"phaseChange[" << cluster <<
"]: " << phaseChange[cluster] << std::endl;
414 std::cout <<
"dcOffset[" << cluster <<
"]: " << dcOffset[cluster] << std::endl;
virtual void moveMotors(double dt)
std::deque< double > tensionHistory
virtual vector< vector< double > > transformActions(vector< vector< double > > act)
const std::vector< tgBasicActuator * > & getAllMuscles() const
std::deque< double > restLengths
virtual void setControlInput(double input)
Contains the definition of class Escape_T6Model. $Id$.
A class to read a learning configuration from a .ini file.
A series of functions to assist with file input/output.
static std::string getResourcePath(std::string relPath)
Contains the definition of class AnnealEvolution. Adapting NeuroEvolution to do Simulated Annealing...
virtual void onSetup(Escape_T6Model &subject)
Contains the definition of class tgBasicActuator.
std::vector< double > getBallCOM()
std::vector< T * > find(const tgTagSearch &tagSearch)
virtual void applyActions(Escape_T6Model &subject, vector< vector< double > > act)
Defines a class AnnealAdapter to pass parameters from AnnealEvolution to a controller. Adapting NeuroEvolution to do Simulated Annealing.
virtual void onStep(Escape_T6Model &subject, double dt)
void initialize(AnnealEvolution *evo, bool isLearning, configuration config)
virtual void onTeardown(Escape_T6Model &subject)