46 # define M_PI 3.14159265358979323846
50 EscapeController::EscapeController(
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);
103 throw std::invalid_argument(
"dt is not positive");
107 setPreferredMuscleLengths(subject, dt);
108 const std::vector<tgBasicActuator*> muscles = subject.
getAllMuscles();
111 for (
size_t i = 0; i < muscles.size(); ++i)
114 assert(pMuscle != NULL);
122 std::vector<double> scores;
123 double distance = displacement(subject);
124 double energySpent = totalEnergySpent(subject);
127 scores.push_back(distance);
128 scores.push_back(energySpent);
130 std::cout <<
"Tearing down" << std::endl;
131 evolutionAdapter.endEpisode(scores);
144 bool usingManualParams =
false;
145 std::vector <double> manualParams(4 * nClusters, 1);
146 if (usingManualParams) {
147 std::cout <<
"Using manually set parameters\n";
148 std::string filename =
"logs/paramSortedBestTrials.dat";
150 manualParams = readManualParams(lineNumber, filename);
153 double pretension = 0.90;
155 double mins[4] = {m_initialLengths * (pretension - maxStringLengthFactor),
161 double maxes[4] = {m_initialLengths * (pretension + maxStringLengthFactor),
165 double ranges[4] = {maxes[0]-mins[0], maxes[1]-mins[1], maxes[2]-mins[2], maxes[3]-mins[3]};
167 for(
int i=0;i<actions.size();i++) {
168 for (
int j=0; j<actions[i].size(); j++) {
169 if (usingManualParams) {
170 actions[i][j] = manualParams[i*actions[i].size() + j]*(ranges[j])+mins[j];
172 actions[i][j] = actions[i][j]*(ranges[j])+mins[j];
184 assert(actions.size() == clusters.size());
187 for (
size_t cluster = 0; cluster < clusters.size(); cluster++) {
188 amplitude[cluster] = actions[cluster][0];
189 angularFrequency[cluster] = actions[cluster][1];
190 phaseChange[cluster] = actions[cluster][2];
191 dcOffset[cluster] = actions[cluster][3];
192 dcOffset[cluster] = 1;
197 void EscapeController::setupAdapter() {
201 if (configPath !=
"")
210 std::string configAnnealEvolution = path + configName;
212 bool isLearning =
true;
214 configEvolutionAdapter.readFile(configAnnealEvolution);
216 evolutionAdapter.
initialize(evo, isLearning, configEvolutionAdapter);
219 double EscapeController::totalEnergySpent(
EscapeModel& subject) {
220 double totalEnergySpent=0;
222 std::vector<tgBasicActuator* > tmpStrings = subject.
getAllMuscles();
223 for(
int i=0; i<tmpStrings.size(); i++)
230 const double previousLength = stringHist.
restLengths[j-1];
231 const double currentLength = stringHist.
restLengths[j];
233 double motorSpeed = (currentLength-previousLength);
236 const double workDone = previousTension * motorSpeed;
237 totalEnergySpent += workDone;
240 return totalEnergySpent;
245 void EscapeController::setPreferredMuscleLengths(
EscapeModel& subject,
double dt) {
252 for(
int iMuscle=0; iMuscle < nMuscles; iMuscle++) {
254 const std::vector<tgBasicActuator*> muscles = subject.
getAllMuscles();
257 assert(pMuscle != NULL);
260 oldCluster = cluster;
263 }
else if (iMuscle < 8) {
265 }
else if (iMuscle < 12) {
267 }
else if (iMuscle < 16 ) {
269 }
else if (iMuscle < 18) {
271 }
else if (iMuscle < 20) {
273 }
else if (iMuscle < 22) {
279 double newLength = amplitude[cluster] * sin(angularFrequency[cluster] * m_totalTime + phase) + dcOffset[cluster];
280 double minLength = m_initialLengths * (1-maxStringLengthFactor);
281 double maxLength = m_initialLengths * (1+maxStringLengthFactor);
282 if (newLength <= minLength) {
283 newLength = minLength;
284 }
else if (newLength >= maxLength) {
285 newLength = maxLength;
288 if (oldCluster != cluster) {
289 phase += phaseChange[cluster];
312 void EscapeController::populateClusters(
EscapeModel& subject) {
313 for(
int cluster=0; cluster < nClusters; cluster++) {
314 std::ostringstream ss;
316 std::string suffix = ss.str();
317 std::vector <tgBasicActuator*> musclesInThisCluster = subject.
find<
tgBasicActuator>(
"muscle cluster" + suffix);
318 clusters[cluster] = std::vector<tgBasicActuator*>(musclesInThisCluster);
322 void EscapeController::initializeSineWaves() {
323 amplitude =
new double[nClusters];
324 angularFrequency =
new double[nClusters];
325 phaseChange =
new double[nClusters];
326 dcOffset =
new double[nClusters];
329 double EscapeController::displacement(
EscapeModel& subject) {
330 std::vector<double> finalPosition = subject.
getBallCOM();
335 const double newX = finalPosition[0];
336 const double newZ = finalPosition[2];
337 const double oldX = initPosition[0];
338 const double oldZ = initPosition[2];
340 const double distanceMoved = sqrt((newX-oldX) * (newX-oldX) +
341 (newZ-oldZ) * (newZ-oldZ));
342 return distanceMoved;
345 std::vector<double> EscapeController::readManualParams(
int lineNumber, std::string filename) {
346 assert(lineNumber > 0);
347 std::vector<double> result(32, 1.0);
349 std::ifstream infile(filename.c_str(), std::ifstream::in);
352 if (infile.is_open()) {
353 std::cout <<
"OPENED FILE\n";
354 for (
int i=0; i<lineNumber; i++) {
355 getline(infile, line);
359 std::cerr <<
"Error: Manual Parameters file not found\n";
366 std::stringstream lineStream(line);
369 while(getline(lineStream,cell,
',')) {
370 result[iCell] = atof(cell.c_str());
374 bool tweaking =
false;
377 for (
int i=0; i < result.size(); i++) {
378 std::cout<<
"Entered Cell " << i <<
": " << result[i] <<
"\n";
379 double seed = ((double) (rand() % 100)) / 100;
380 result[i] += (0.01 * seed) - 0.005;
383 std::cerr <<
"WARNING: Not changing manual input parameters\n";
389 void EscapeController::printSineParams() {
390 for (
size_t cluster = 0; cluster < clusters.size(); cluster++) {
391 std::cout <<
"amplitude[" << cluster <<
"]: " << amplitude[cluster] << std::endl;
392 std::cout <<
"angularFrequency[" << cluster <<
"]: " << angularFrequency[cluster] << std::endl;
393 std::cout <<
"phaseChange[" << cluster <<
"]: " << phaseChange[cluster] << std::endl;
394 std::cout <<
"dcOffset[" << cluster <<
"]: " << dcOffset[cluster] << std::endl;
Contains the definition of class EscapeModel. $Id$.
virtual void moveMotors(double dt)
std::deque< double > tensionHistory
virtual void onSetup(EscapeModel &subject)
virtual void onTeardown(EscapeModel &subject)
std::deque< double > restLengths
virtual void setControlInput(double input)
A class to read a learning configuration from a .ini file.
A series of functions to assist with file input/output.
virtual void applyActions(EscapeModel &subject, std::vector< std::vector< double > > act)
static std::string getResourcePath(std::string relPath)
Contains the definition of class AnnealEvolution. Adapting NeuroEvolution to do Simulated Annealing...
Contains the definition of class tgBasicActuator.
virtual std::vector< std::vector< double > > transformActions(std::vector< std::vector< double > > act)
const std::vector< tgBasicActuator * > & getAllMuscles() const
std::vector< T * > find(const tgTagSearch &tagSearch)
Defines a class AnnealAdapter to pass parameters from AnnealEvolution to a controller. Adapting NeuroEvolution to do Simulated Annealing.
virtual void onStep(EscapeModel &subject, double dt)
void initialize(AnnealEvolution *evo, bool isLearning, configuration config)
Contains the definition of class EscapeController.
std::vector< double > getBallCOM()