NTRT Simulator  Version: Master
 All Classes Namespaces Files Functions Variables Typedefs Friends Pages
ScarrArmController.cpp
Go to the documentation of this file.
1 /*
2  * Copyright © 2015, United States Government, as represented by the
3  * Administrator of the National Aeronautics and Space Administration.
4  * All rights reserved.
5  *
6  * The NASA Tensegrity Robotics Toolkit (NTRT) v1 platform is licensed
7  * under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  * http://www.apache.org/licenses/LICENSE-2.0.
11  *
12  * Unless required by applicable law or agreed to in writing,
13  * software distributed under the License is distributed on an
14  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
15  * either express or implied. See the License for the specific language
16  * governing permissions and limitations under the License.
17  */
18 
27 // This module
28 #include "ScarrArmController.h"
29 // This application
30 #include "ScarrArmModel.h"
31 // This library
32 #include "core/tgBasicActuator.h"
33 // The C++ Standard Library
34 #include <cassert>
35 #include <stdexcept>
36 #include <vector>
37 
38 # define M_PI 3.14159265358979323846
39 
40 using namespace std;
41 
42 //Constructor using the model subject and a single pref length for all muscles.
43 ScarrArmController::ScarrArmController(const double initialLength, double timestep) :
44  m_initialLengths(initialLength),
45  m_totalTime(0.0),
46  dt(timestep) {}
47 
48 //Fetch all the muscles and set their preferred length
50  this->m_totalTime=0.0;
51  const double olecranonfascia_length = 4;
52  const double brachioradialis_length = 12;
53  const double anconeus_length = 6;
54  const double supportstring_length = 0.5;
55 
56  const std::vector<tgBasicActuator*> olecranonfascia = subject.find<tgBasicActuator>("olecranon");
57  const std::vector<tgBasicActuator*> anconeus = subject.find<tgBasicActuator>("anconeus");
58  const std::vector<tgBasicActuator*> brachioradialis = subject.find<tgBasicActuator>("brachioradialis");
59  const std::vector<tgBasicActuator*> supportstrings = subject.find<tgBasicActuator>("support");
60 
61  for (size_t i=0; i<olecranonfascia.size(); i++) {
62  tgBasicActuator * const pMuscle = olecranonfascia[i];
63  assert(pMuscle != NULL);
64  pMuscle->setControlInput(olecranonfascia_length, dt);
65  }
66 
67  // using for loops to anticipate more muscle fibers in the future
68  for (size_t i=0; i<anconeus.size(); i++) {
69  tgBasicActuator * const pMuscle = anconeus[i];
70  assert(pMuscle != NULL);
71  pMuscle->setControlInput(anconeus_length, dt);
72  }
73 
74  for (size_t i=0; i<brachioradialis.size(); i++) {
75  tgBasicActuator * const pMuscle = brachioradialis[i];
76  assert(pMuscle != NULL);
77  pMuscle->setControlInput(brachioradialis_length, dt);
78  }
79 
80  for (size_t i=0; i<supportstrings.size(); i++) {
81  tgBasicActuator * const pMuscle = supportstrings[i];
82  assert(pMuscle != NULL);
83  pMuscle->setControlInput(supportstring_length, dt);
84  cout << "string " << i << "\n";
85  }
86 }
87 
88 // Set target length of each muscle, then move motors accordingly
89 void ScarrArmController::onStep(ScarrArmModel& subject, double dt) {
90  // Update controller's internal time
91  if (dt <= 0.0) { throw std::invalid_argument("dt is not positive"); }
92  m_totalTime+=dt;
93 
94  setBrachioradialisTargetLength(subject, dt); //pitch
95  setAnconeusTargetLength(subject, dt); //yaw
96  moveAllMotors(subject, dt);
97  //updateActions(dt);
98 }
99 
100 void ScarrArmController::setBrachioradialisTargetLength(ScarrArmModel& subject, double dt) {
101  const double mean_brachioradialis_length = 12; //TODO: define according to vars
102  double newLength = 0;
103  const double amplitude = mean_brachioradialis_length/1;
104  const double angular_freq = 2;
105  const double phase = 0;
106  const double dcOffset = mean_brachioradialis_length;
107  const std::vector<tgBasicActuator*> brachioradialis = subject.find<tgBasicActuator>("brachioradialis");
108 
109  for (size_t i=0; i<brachioradialis.size(); i++) {
110  tgBasicActuator * const pMuscle = brachioradialis[i];
111  assert(pMuscle != NULL);
112  cout <<"t: " << pMuscle->getCurrentLength() << endl;
113  //newLength = amplitude * sin(angular_freq * m_totalTime + phase) + dcOffset;
114  newLength = dcOffset - amplitude*m_totalTime/5;
115  if(newLength < dcOffset/8) {
116  newLength = dcOffset/8;
117  }
118 
119  if(m_totalTime > 15) {
120  m_totalTime = 0;
121  }
122  std::cout<<"calculating brachioradialis target length:" << newLength << "\n";
123  std::cout<<"m_totalTime: " << m_totalTime << "\n";
124  pMuscle->setControlInput(newLength, dt);
125  cout <<"t+1: " << pMuscle->getCurrentLength() << endl;
126  }
127 }
128 
129 void ScarrArmController::setAnconeusTargetLength(ScarrArmModel& subject, double dt) {
130  const double mean_anconeus_length = 6; //TODO: define according to vars
131  double newLength = 0;
132  const double amplitude = mean_anconeus_length/1;
133  const double angular_freq = 2;
134  const double phaseleft = 0;
135  const double phaseright = phaseleft + M_PI;
136  const double dcOffset = mean_anconeus_length;
137  const std::vector<tgBasicActuator*> anconeusleft = subject.find<tgBasicActuator>("right anconeus");
138  const std::vector<tgBasicActuator*> anconeusright = subject.find<tgBasicActuator>("left anconeus");
139 
140  for (size_t i=0; i<anconeusleft.size(); i++) {
141  tgBasicActuator * const pMuscle = anconeusleft[i];
142  assert(pMuscle != NULL);
143  if(m_totalTime > 5) {
144  newLength = amplitude * sin(angular_freq * m_totalTime + phaseleft) + dcOffset;
145  } else {
146  newLength = dcOffset;
147  }
148  pMuscle->setControlInput(newLength, dt);
149  }
150 
151  for (size_t i=0; i<anconeusright.size(); i++) {
152  tgBasicActuator * const pMuscle = anconeusright[i];
153  assert(pMuscle != NULL);
154  if(m_totalTime > 5) {
155  newLength = amplitude * sin(angular_freq * m_totalTime + phaseright) + dcOffset;
156  } else {
157  newLength = dcOffset;
158  }
159  pMuscle->setControlInput(newLength, dt);
160  }
161 }
162 
163 //Move motors for all the muscles
164 void ScarrArmController::moveAllMotors(ScarrArmModel& subject, double dt) {
165  const std::vector<tgBasicActuator*> muscles = subject.getAllMuscles();
166  for (size_t i = 0; i < muscles.size(); ++i) {
167  tgBasicActuator * const pMuscle = muscles[i];
168  assert(pMuscle != NULL);
169  pMuscle->moveMotors(dt);
170  }
171 
172 }
173 
174 // Get actions from evolutionAdapter, transform them to this structure, and apply them
175 void ScarrArmController::updateActions(ScarrArmModel& subject, double dt) {
176  /*vector<double> state=getState();
177  vector< vector<double> > actions;
178 
179  //get the actions (between 0 and 1) from evolution (todo)
180  actions=evolutionAdapter.step(dt,state);
181 
182  //transform them to the size of the structure
183  actions = transformActions(actions);
184 
185  //apply these actions to the appropriate muscles according to the sensor values
186  applyActions(subject,actions);
187  */
188 }
189 
190 //Scale actions according to Min and Max length of muscles.
191 vector< vector <double> > ScarrArmController::transformActions(vector< vector <double> > actions)
192 {
193  double min=6;
194  double max=11;
195  double range=max-min;
196  double scaledAct;
197  for(unsigned i=0;i<actions.size();i++) {
198  for(unsigned j=0;j<actions[i].size();j++) {
199  scaledAct=actions[i][j]*(range)+min;
200  actions[i][j]=scaledAct;
201  }
202  }
203  return actions;
204 }
205 
206 //Pick particular muscles (according to the structure's state) and apply the given actions one by one
207 void ScarrArmController::applyActions(ScarrArmModel& subject, vector< vector <double> > act)
208 {
209  //Get All the muscles of the subject
210  const std::vector<tgBasicActuator*> muscles = subject.getAllMuscles();
211  //Check if the number of the actions match the number of the muscles
212  if(act.size() != muscles.size()) {
213  cout<<"Warning: # of muscles: "<< muscles.size() << " != # of actions: "<< act.size()<<endl;
214  return;
215  }
216  //Apply actions (currently in a random order)
217  for (size_t i = 0; i < muscles.size(); ++i) {
218  tgBasicActuator * const pMuscle = muscles[i];
219  assert(pMuscle != NULL);
220  //cout<<"i: "<<i<<" length: "<<act[i][0]<<endl;
221  pMuscle->setControlInput(act[i][0]);
222  }
223 }
virtual void moveMotors(double dt)
virtual void setControlInput(double input)
virtual void onSetup(ScarrArmModel &subject)
Contains the definition of class ScarrArmController.
Contains the definition of class tgBasicActuator.
std::vector< T * > find(const tgTagSearch &tagSearch)
Definition: tgModel.h:128
virtual void onStep(ScarrArmModel &subject, double dt)
Contains the definition of class ScarrArmModel. $Id$.
const std::vector< tgBasicActuator * > & getAllMuscles() const
virtual const double getCurrentLength() const
ScarrArmController(const double prefLength, double timestep)