NTRT Simulator
 All Classes Files Functions Variables Typedefs Friends Pages
tgCPGStringControl.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 
19 #include "tgCPGStringControl.h"
20 
21 #include "core/Muscle2P.h"
22 #include "core/ImpedanceControl.h"
23 #include "util/CPGEquations.h"
24 
25 #include <iostream>
26 #include <stdexcept>
27 
28 tgCPGStringControl::tgCPGStringControl(const double controlStep) :
29 m_controlTime(0.0),
30 m_controlStep(controlStep),
31 m_commandedTension(0.0),
32 m_pFromBody(NULL),
33 m_pToBody(NULL)
34 {
35  if (m_controlStep < 0.0)
36  {
37  throw std::invalid_argument("Negative control step");
38  }
39 }
40 
41 tgCPGStringControl::~tgCPGStringControl()
42 {
43  // We don't own these
44  m_pFromBody = NULL;
45  m_pToBody = NULL;
46 }
47 
49 {
50  m_controlLength = subject.getStartLength();
51  m_pFromBody = subject.getMuscle()->anchor1->attachedBody;
52  m_pToBody = subject.getMuscle()->anchor2->attachedBody;
53 }
54 
55 void tgCPGStringControl::onStep(tgLinearString& subject, double dt)
56 {
57  m_controlTime += dt;
58 
61  if (m_controlTime >= m_controlStep)
62  {
63  m_commandedTension = motorControl().control(&subject, dt, controlLength(), getCPGValue());
64  m_controlTime = 0;
65  }
66 }
67 
68 void tgCPGStringControl::assignNodeNumber (CPGEquations& CPGSys, array_2D nodeParams)
69 {
70  // Ensure that this hasn't already been assigned
71  assert(m_nodeNumber == -1);
72 
73  m_pCPGSystem = &CPGSys;
74 
75  std::vector<double> params (7);
76  params[0] = nodeParams[0][0]; // Frequency Offset
77  params[1] = nodeParams[0][0]; // Frequency Scale
78  params[2] = nodeParams[0][1]; // Radius Offset
79  params[3] = nodeParams[0][1]; // Radius Scale
80  params[4] = 20.0; // rConst (a constant)
81  params[5] = 0.0; // dMin for descending commands
82  params[6] = 5.0; // dMax for descending commands
83 
84  m_nodeNumber = m_pCPGSystem->addNode(params);
85 }
86 
87 void
88 tgCPGStringControl::setConnectivity(const std::vector<tgCPGStringControl*>& allStrings,
89  array_4D edgeParams)
90 {
91  assert(m_nodeNumber >= 0);
92 
93  int muscleSize = edgeParams.shape()[1];
94 
95  std::vector<int> connectivityList;
96  std::vector<double> weights;
97  std::vector<double> phases;
98 
99  // Assuming all coupling is two way, there ought to be a way
100  // to search faster than O((2N)^2) since every other
101  // string has to call this. Ideas are welcome
102  for (int i = 0; i < allStrings.size(); i++)
103  {
104  if (this != allStrings[i])
105  {
106  // Make sure we're dealing with the same system
107  assert(m_pCPGSystem == allStrings[i]->getCPGSys());
108 
109  const btRigidBody* theirFromGroup = allStrings[i]->getFromBody();
110  const btRigidBody* theirToGroup = allStrings[i]->getToBody();
111 
112  // "All to all" connectivity for shared rigid bodies
113  if(m_pFromBody == theirFromGroup ||
114  m_pToBody == theirToGroup ||
115  m_pFromBody == theirToGroup ||
116  m_pToBody == theirFromGroup)
117  {
118  int theirMuscle = allStrings[i]->getNodeNumber();
119  // Integer division: -1 is behind, 0 is same row 1 is ahead
120  int rp = ((m_nodeNumber - theirMuscle) / muscleSize) + 1;
121  int j = m_nodeNumber % muscleSize;
122  int k = theirMuscle % muscleSize;
123  connectivityList.push_back(theirMuscle);
124  // Upper triangular matrix, lower number always goes first
125  if(j > k){
126  weights.push_back(edgeParams[rp][k][j][0]);
127  phases.push_back(edgeParams[rp][k][j][1]);
128  }
129  else
130  {
131  weights.push_back(edgeParams[rp][j][k][0]);
132  phases.push_back(edgeParams[rp][j][k][1]);
133  }
134  }
135  }
136  }
137 
138  m_pCPGSystem->defineConnections(m_nodeNumber, connectivityList, weights, phases);
139 }
140 
141 void tgCPGStringControl::setupControl(ImpedanceControl& ipc)
142 {
143  tgBaseCPGNode::setupControl(ipc);
144 }
145 
146 void tgCPGStringControl::setupControl(ImpedanceControl& ipc,
147  double controlLength)
148 {
149  if (controlLength < 0.0)
150  {
151  throw std::invalid_argument("Negative control length");
152  }
153 
154  m_controlLength = controlLength;
155  tgBaseCPGNode::setupControl(ipc);
156 }
const Muscle2P * getMuscle() const
virtual void onAttach(tgLinearString &subject)
virtual void onStep(tgLinearString &subject, double dt)
const CPGEquations * getCPGSys() const
Definitions of classes Muscle2P and MuscleAnchor.
double control(tgBaseString *const mString, double deltaTimeSeconds, double newPosition, double offsetVel=0)
Control Functions.
void setConnectivity(const std::vector< tgCPGStringControl * > &allStrings, array_4D edgeParams)
Contains the definition of class ImpedanceControl. $Id$.
void assignNodeNumber(CPGEquations &CPGSys, array_2D nodeParams)
Definition of class CPGEquations.
virtual const double getStartLength() const