motors.cpp
1 /********************************************************************************
2  * FARSA Experiments Library *
3  * Copyright (C) 2007-2012 *
4  * Gianluca Massera <emmegian@yahoo.it> *
5  * Stefano Nolfi <stefano.nolfi@istc.cnr.it> *
6  * Tomassino Ferrauto <tomassino.ferrauto@istc.cnr.it> *
7  * *
8  * This program is free software; you can redistribute it and/or modify *
9  * it under the terms of the GNU General Public License as published by *
10  * the Free Software Foundation; either version 2 of the License, or *
11  * (at your option) any later version. *
12  * *
13  * This program is distributed in the hope that it will be useful, *
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
16  * GNU General Public License for more details. *
17  * *
18  * You should have received a copy of the GNU General Public License *
19  * along with this program; if not, write to the Free Software *
20  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA *
21  ********************************************************************************/
22 
23 #include "motors.h"
24 #include "configurationparameters.h"
25 #include "configurationhelper.h"
26 #include "randomgenerator.h"
27 #include "motorcontrollers.h"
28 #include "logger.h"
29 #include <QStringList>
30 #include <QMap>
31 
32 namespace farsa {
33 
35  Motor(params, prefix),
36  m_additionalOutputs(ConfigurationHelper::getUnsignedInt(params, prefix + "additionalOutputs", 1)),
37  m_neuronsIteratorResource(actualResourceNameForMultirobot(ConfigurationHelper::getString(params, prefix + "neuronsIterator", "neuronsIterator"))),
38  m_additionalOutputsResource(actualResourceNameForMultirobot(ConfigurationHelper::getString(params, prefix + "additionalOutputsResource", "additionalOutputs"))),
39  m_neuronsIterator(NULL)
40 {
42 
43  for (unsigned int i = 0; i < m_additionalOutputs.size(); i++) {
44  m_additionalOutputs[i] = 0.0;
45  }
46 }
47 
49 {
50  // Removing resources
51  try {
53  } catch (...) {
54  // Doing nothing, this is here just to prevent throwing an exception from the destructor
55  }
56 }
57 
58 void FakeMotor::save(ConfigurationParameters& params, QString prefix)
59 {
60  Motor::save( params, prefix );
61  params.startObjectParameters(prefix, "FakeMotor", this);
62  params.createParameter(prefix, "additionalOutputs", QString::number(m_additionalOutputs.size()));
63  params.createParameter(prefix, "neuronsIterator", m_neuronsIteratorResource);
64  params.createParameter(prefix, "additionalOutputsResource", m_additionalOutputsResource);
65 }
66 
67 void FakeMotor::describe(QString type)
68 {
69  Motor::describe(type);
70 
71  Descriptor d = addTypeDescription(type, "Adds output neurons that can be used for custom operations", "With this motor you can specify how many additional outputs are needed in the controller. This also declares a resource that can be used to access the additional outputs");
72  d.describeInt("additionalOutputs").def(1).limits(1,100).props(IsMandatory).help("The number of additional outputs that will be added to the controller (default 1)");
73  d.describeString("neuronsIterator").def("neuronsIterator").help("The name of the resource associated with the neural network iterator (default is \"neuronsIterator\")");
74  d.describeString("additionalOutputsResource").def("additionalOutputs").help("The name of the resource associated with the vector of additional outputs (default is \"additionalOutputs\")");
75 }
76 
78 {
79  // Checking all resources we need exist
81 
82  ResourcesLocker locker(this);
83 
84  // Copying the output inside the vector of additional outputs
86  for (unsigned int i = 0; i < m_additionalOutputs.size(); i++, m_neuronsIterator->nextNeuron()) {
88  }
89 }
90 
92 {
93  return m_additionalOutputs.size();
94 }
95 
97 {
98  // Calling parent function
100 
101  // Now declaring our resource
103 }
104 
105 void FakeMotor::resourceChanged(QString resourceName, ResourceChangeType changeType)
106 {
107  if (changeType == Deleted) {
109  return;
110  }
111 
112  if (resourceName == m_neuronsIteratorResource) {
113  m_neuronsIterator = getResource<NeuronsIterator>();
115  for(int i = 0; i < size(); i++, m_neuronsIterator->nextNeuron()) {
116  m_neuronsIterator->setGraphicProperties("Fk" + QString::number(i), 0.0, 1.0, Qt::red);
117  }
118  } else if (resourceName != m_additionalOutputsResource) {
119  Logger::info("Unknown resource " + resourceName + " for " + name());
120  }
121 }
122 
124  m_k(0.3),
125  m_maxVelocity(20.0)
126 {
127 }
128 
129 ProportionalController::ProportionalController(double k, double maxVelocity) :
130  m_k(k),
131  m_maxVelocity(maxVelocity)
132 {
133 }
134 
136  m_k(other.m_k),
137  m_maxVelocity(other.m_maxVelocity)
138 {
139 }
140 
142 {
143  if (this == &other) {
144  return *this;
145  }
146 
147  m_k = other.m_k;
149 
150  return *this;
151 }
152 
154 {
155  // Nothing to do here
156 }
157 
158 real ProportionalController::velocityForJoint(real desired, real current) const
159 {
160  real vel = m_k * (desired - current);
161 
162  if (vel > +m_maxVelocity) {
163  vel = +m_maxVelocity;
164  } else if (vel < -m_maxVelocity) {
165  vel = -m_maxVelocity;
166  }
167 
168  return vel;
169 }
170 
171 } // end namespace farsa
172