NTRT Simulator  Version: Master
 All Classes Namespaces Files Functions Variables Typedefs Friends Pages
tgCPGActuatorControl.cpp
1 /*
2  * Copyright © 2012, 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 #include "tgCPGActuatorControl.h"
28 
29 #include "core/tgSpringCable.h"
32 #include "core/tgBasicActuator.h"
35 #include "util/CPGEquations.h"
36 #include "core/tgCast.h"
37 
38 // The C++ Standard Library
39 #include <iostream>
40 #include <stdexcept>
41 #include <vector>
42 
43 tgCPGActuatorControl::tgCPGActuatorControl(const double controlStep) :
44 m_controlTime(0.0),
45 m_totalTime(0.0),
46 m_controlStep(controlStep),
47 m_commandedTension(0.0),
48 m_pFromBody(NULL),
49 m_pToBody(NULL)
50 {
51  if (m_controlStep < 0.0)
52  {
53  throw std::invalid_argument("Negative control step");
54  }
55 }
56 
57 tgCPGActuatorControl::~tgCPGActuatorControl()
58 {
59  // We don't own these
60  m_pFromBody = NULL;
61  m_pToBody = NULL;
62 }
63 
65 {
66  m_controlLength = subject.getStartLength();
67 
68  // tgSpringCable doesn't know about bullet anchors, so we have to cast here to get the rigid bodies
69  std::vector<const tgBulletSpringCableAnchor*> anchors =
70  tgCast::filter<const tgSpringCableAnchor, const tgBulletSpringCableAnchor>(subject.getSpringCable()->getAnchors());
71 
72  std::size_t n = anchors.size();
73  assert(n >= 2);
74 
75  m_pFromBody = anchors[0]->attachedBody;
76  m_pToBody = anchors[n - 1]->attachedBody;
77 }
78 
80 {
81  m_controlTime += dt;
82  m_totalTime += dt;
85 
86  // Workaround until we implement PID
87  tgBasicActuator& m_sca = *(tgCast::cast<tgSpringCableActuator, tgBasicActuator>(subject));
88 
90  {
91 
92  m_commandedTension = motorControl().control(m_sca, m_controlTime, controlLength(), getCPGValue());
93 
94  m_controlTime = 0;
95  }
96  else
97  {
98  m_sca.moveMotors(dt);
99  }
100 }
101 
102 void tgCPGActuatorControl::assignNodeNumber (CPGEquations& CPGSys, array_2D nodeParams)
103 {
104  // Ensure that this hasn't already been assigned
105  assert(m_nodeNumber == -1);
106 
107  m_pCPGSystem = &CPGSys;
108 
109  std::vector<double> params (7);
110  params[0] = nodeParams[0][0]; // Frequency Offset
111  params[1] = nodeParams[0][0]; // Frequency Scale
112  params[2] = nodeParams[0][1]; // Radius Offset
113  params[3] = nodeParams[0][1]; // Radius Scale
114  params[4] = 20.0; // rConst (a constant)
115  params[5] = 0.0; // dMin for descending commands
116  params[6] = 5.0; // dMax for descending commands
117 
118  m_nodeNumber = m_pCPGSystem->addNode(params);
119 }
120 
121 void
122 tgCPGActuatorControl::setConnectivity(const std::vector<tgCPGActuatorControl*>& allStrings,
123  array_4D edgeParams)
124 {
125  assert(m_nodeNumber >= 0);
126 
127  int muscleSize = edgeParams.shape()[1];
128 
129  std::vector<int> connectivityList;
130  std::vector<double> weights;
131  std::vector<double> phases;
132 
133  // Assuming all coupling is two way, there ought to be a way
134  // to search faster than O((2N)^2) since every other
135  // string has to call this. Ideas are welcome
136  for (int i = 0; i < allStrings.size(); i++)
137  {
138  if (this != allStrings[i])
139  {
140  // Make sure we're dealing with the same system
141  assert(m_pCPGSystem == allStrings[i]->getCPGSys());
142 
143  const btRigidBody* theirFromGroup = allStrings[i]->getFromBody();
144  const btRigidBody* theirToGroup = allStrings[i]->getToBody();
145 
146  // "All to all" connectivity for shared rigid bodies
147  if(m_pFromBody == theirFromGroup ||
148  m_pToBody == theirToGroup ||
149  m_pFromBody == theirToGroup ||
150  m_pToBody == theirFromGroup)
151  {
152  int theirMuscle = allStrings[i]->getNodeNumber();
153  // Integer division: -1 is behind, 0 is same row 1 is ahead
154  int rp = ((m_nodeNumber - theirMuscle) / muscleSize) + 1;
155  int j = m_nodeNumber % muscleSize;
156  int k = theirMuscle % muscleSize;
157  connectivityList.push_back(theirMuscle);
158  // Upper triangular matrix, lower number always goes first
159  if(j > k){
160  weights.push_back(edgeParams[rp][k][j][0]);
161  phases.push_back(edgeParams[rp][k][j][1]);
162  }
163  else
164  {
165  weights.push_back(edgeParams[rp][j][k][0]);
166  phases.push_back(edgeParams[rp][j][k][1]);
167  }
168  }
169  }
170  }
171 
172  m_pCPGSystem->defineConnections(m_nodeNumber, connectivityList, weights, phases);
173 }
174 
175 void tgCPGActuatorControl::setupControl(tgImpedanceController& ipc)
176 {
177  tgBaseCPGNode::setupControl(ipc);
178 }
179 
180 void tgCPGActuatorControl::setupControl(tgImpedanceController& ipc,
181  double controlLength)
182 {
183  if (controlLength < 0.0)
184  {
185  throw std::invalid_argument("Negative control length");
186  }
187 
188  m_controlLength = controlLength;
189  tgBaseCPGNode::setupControl(ipc);
190 }
Contains the definition of class ImpedanceControl. $Id$.
Definitions of class tgSpringCable.
virtual void moveMotors(double dt)
virtual void onStep(tgSpringCableActuator &subject, double dt)
virtual const double getStartLength() const
void setConnectivity(const std::vector< tgCPGActuatorControl * > &allStrings, array_4D edgeParams)
Utility class for class casting and filtering collections by type.
const CPGEquations * getCPGSys() const
virtual void onAttach(tgSpringCableActuator &subject)
Definition of the tgCPGStringControl observer class.
Contains the definition of abstract base class tgSpringCableActuator. Assumes that the string is line...
Contains the definition of class tgBasicActuator.
virtual const std::vector< const tgSpringCableAnchor * > getAnchors() const =0
Definitions of class tgBulletSpringCableAnchor, formerly muscleAnchor.
Definition of class CPGEquations.
void assignNodeNumber(CPGEquations &CPGSys, array_2D nodeParams)
Definitions of class tgSpringCableAnchor.
double control(tgBasicController &mLocalController, double deltaTimeSeconds, double newPosition, double offsetVel=0)
Control Functions.
const tgSpringCable * getSpringCable() const