14
14
# sot-application. If not, see <http://www.gnu.org/licenses/>.
15
15
16
16
#!/usr/bin/env python
17
+ import warnings
17
18
18
19
from dynamic_graph .sot .core .feature_position import FeaturePosition
19
20
from dynamic_graph .sot .core import FeatureGeneric , FeatureJointLimits , Task , \
20
21
JointLimitator , SOT
22
+ from dynamic_graph .sot .core .matrix_util import matrixToTuple
21
23
from dynamic_graph import plug
24
+ from dynamic_graph .sot .core import GainAdaptive
25
+ from numpy import identity
22
26
23
27
class Solver :
24
28
@@ -61,21 +65,21 @@ def remove (self, task):
61
65
def __str__ (self ):
62
66
return self .sot .display ()
63
67
64
- def initializeSignals (robot ):
68
+ def initializeSignals (application , robot ):
65
69
"""
66
70
For portability, make some signals accessible as attributes.
67
71
"""
68
- robot .comRef = robot .featureComDes .errorIN
69
- robot .zmpRef = robot .device .zmp
70
- robot .com = robot .dynamic .com
71
- robot .comSelec = robot .featureCom .selec
72
- robot .comdot = robot .featureComDes .errordotIN
72
+ application .comRef = application .featureComDes .errorIN
73
+ application .zmpRef = robot .device .zmp
74
+ application .com = robot .dynamic .com
75
+ application .comSelec = application .featureCom .selec
76
+ application .comdot = application .featureComDes .errordotIN
73
77
74
78
def createCenterOfMassFeatureAndTask (robot ,
75
79
featureName , featureDesName ,
76
80
taskName ,
77
81
selec = '111' ,
78
- gain = 1. ):
82
+ ingain = 1. ):
79
83
robot .dynamic .com .recompute (0 )
80
84
robot .dynamic .Jcom .recompute (0 )
81
85
@@ -86,16 +90,19 @@ def createCenterOfMassFeatureAndTask(robot,
86
90
featureComDes = FeatureGeneric (featureDesName )
87
91
featureComDes .errorIN .value = robot .dynamic .com .value
88
92
featureCom .setReference (featureComDes .name )
89
- comTask = Task (taskName )
90
- comTask .add (featureName )
91
- comTask .controlGain .value = gain
92
- return (featureCom , featureComDes , comTask )
93
+ taskCom = Task (taskName )
94
+ taskCom .add (featureName )
95
+ gainCom = GainAdaptive ('gain' + taskName )
96
+ gainCom .setConstant (ingain )
97
+ plug (gainCom .gain , taskCom .controlGain )
98
+ plug (taskCom .error , gainCom .error )
99
+ return (featureCom , featureComDes , taskCom , gainCom )
93
100
94
101
def createOperationalPointFeatureAndTask (robot ,
95
102
operationalPointName ,
96
103
featureName ,
97
104
taskName ,
98
- gain = .2 ):
105
+ ingain = .2 ):
99
106
jacobianName = 'J{0}' .format (operationalPointName )
100
107
robot .dynamic .signal (operationalPointName ).recompute (0 )
101
108
robot .dynamic .signal (jacobianName ).recompute (0 )
@@ -106,21 +113,46 @@ def createOperationalPointFeatureAndTask(robot,
106
113
robot .dynamic .signal (operationalPointName ).value )
107
114
task = Task (taskName )
108
115
task .add (featureName )
109
- task .controlGain .value = gain
110
- return (feature , task )
116
+ gain = GainAdaptive ('gain' + taskName )
117
+ gain .setConstant (ingain )
118
+ plug (gain .gain , task .controlGain )
119
+ plug (task .error , gain .error )
120
+ return (feature , task , gain )
111
121
112
- def createBalanceTask (robot , taskName , gain = 1. ):
122
+ def createBalanceTask (robot , application , taskName , ingain = 1. ):
113
123
task = Task (taskName )
114
- task .add (robot .featureCom .name )
115
- task .add (robot .leftAnkle .name )
116
- task .add (robot .rightAnkle .name )
117
- task .controlGain .value = gain
118
- return task
124
+ task .add (application .featureCom .name )
125
+ task .add (application .leftAnkle .name )
126
+ task .add (application .rightAnkle .name )
127
+ gain = GainAdaptive ('gain' + taskName )
128
+ gain .setConstant (ingain )
129
+ plug (gain .gain , task .controlGain )
130
+ plug (task .error , gain .error )
131
+ return (task , gain )
132
+
133
+ def createPostureTask (robot , taskName , ingain = 1. ):
134
+ robot .dynamic .position .recompute (0 )
135
+ feature = FeatureGeneric ('feature' + taskName )
136
+ featureDes = FeatureGeneric ('featureDes' + taskName )
137
+ featureDes .errorIN .value = robot .halfSitting
138
+ plug (robot .dynamic .position ,feature .errorIN )
139
+ feature .setReference (featureDes .name )
140
+ robotDim = len (robot .dynamic .position .value )
141
+ feature .jacobianIN .value = matrixToTuple ( identity (robotDim ) )
142
+ task = Task (taskName )
143
+ task .add (feature .name )
144
+ gain = GainAdaptive ('gain' + taskName )
145
+ plug (gain .gain ,task .controlGain )
146
+ plug (task .error ,gain .error )
147
+ gain .setConstant (ingain )
148
+ return (feature , featureDes , task , gain )
119
149
120
150
121
151
def initialize (robot , solverType = SOT ):
122
152
"""
123
- Tasks are stored into 'tasks' dictionary.
153
+ Tasks are stored into 'tasks' dictionary.
154
+
155
+ WARNING: deprecated, use Application instead
124
156
125
157
For portability, some signals are accessible as attributes:
126
158
- zmpRef: input (vector),
@@ -130,9 +162,11 @@ def initialize (robot, solverType=SOT):
130
162
- comdot: input (vector) reference velocity of the center of mass
131
163
132
164
"""
165
+
166
+ warnings .warn ("The function dynamic_graph.sot.application.velocity.precomputed_tasks.initialize is deprecated. Use dynamic_graph.sot.application.velocity.precomputed_tasks.Application" )
133
167
134
168
# --- center of mass ------------
135
- (robot .featureCom , robot .featureComDes , robot .comTask ) = \
169
+ (robot .featureCom , robot .featureComDes , robot .comTask , robot . gainCom ) = \
136
170
createCenterOfMassFeatureAndTask (robot ,
137
171
'{0}_feature_com' .format (robot .name ),
138
172
'{0}_feature_ref_com' .format (robot .name ),
@@ -141,8 +175,9 @@ def initialize (robot, solverType=SOT):
141
175
# --- operational points tasks -----
142
176
robot .features = dict ()
143
177
robot .tasks = dict ()
178
+ robot .gains = dict ()
144
179
for op in robot .OperationalPoints :
145
- (robot .features [op ], robot .tasks [op ]) = \
180
+ (robot .features [op ], robot .tasks [op ], robot . gains [ op ] ) = \
146
181
createOperationalPointFeatureAndTask (robot ,
147
182
op , '{0}_feature_{1}' .format (robot .name , op ),
148
183
'{0}_task_{1}' .format (robot .name , op ))
@@ -153,13 +188,14 @@ def initialize (robot, solverType=SOT):
153
188
memberName += i .capitalize ()
154
189
setattr (robot , memberName , robot .features [op ])
155
190
robot .tasks ['com' ] = robot .comTask
191
+ robot .gains ['com' ] = robot .gainCom
156
192
robot .waist .selec .value = '011100'
157
193
158
194
# --- balance task --- #
159
- robot .tasks ['balance' ] = \
160
- createBalanceTask (robot , '{0}_task_balance' .format (robot .name ))
195
+ ( robot .tasks ['balance' ], robot . gains [ 'balance' ]) = \
196
+ createBalanceTask (robot , robot , '{0}_task_balance' .format (robot .name ))
161
197
162
- initializeSignals (robot )
198
+ initializeSignals (robot , robot )
163
199
164
200
# --- create solver --- #
165
201
solver = Solver (robot , solverType )
@@ -170,3 +206,75 @@ def initialize (robot, solverType=SOT):
170
206
solver .push (robot .tasks ['right-ankle' ])
171
207
172
208
return solver
209
+
210
+
211
+ class Application (object ):
212
+ """
213
+ Generic application with most used tasks
214
+
215
+ For portability, some signals are accessible as attributes:
216
+ - zmpRef: input (vector),
217
+ - comRef: input (vector).
218
+ - com: output (vector)
219
+ - comSelec input (flag)
220
+ - comdot: input (vector) reference velocity of the center of mass
221
+
222
+ """
223
+ def __init__ (self , robot , solverType = SOT ):
224
+
225
+ self .robot = robot
226
+
227
+ # --- center of mass ------------
228
+ (self .featureCom , self .featureComDes , self .taskCom , self .gainCom ) = \
229
+ createCenterOfMassFeatureAndTask \
230
+ (robot , '{0}_feature_com' .format (robot .name ),
231
+ '{0}_feature_ref_com' .format (robot .name ),
232
+ '{0}_task_com' .format (robot .name ))
233
+
234
+ # --- operational points tasks -----
235
+ self .features = dict ()
236
+ self .tasks = dict ()
237
+ self .gains = dict ()
238
+ for op in robot .OperationalPoints :
239
+ (self .features [op ], self .tasks [op ], self .gains [op ]) = \
240
+ createOperationalPointFeatureAndTask \
241
+ (robot , op , '{0}_feature_{1}' .format (robot .name , op ),
242
+ '{0}_task_{1}' .format (robot .name , op ))
243
+ # define a member for each operational point
244
+ w = op .split ('-' )
245
+ memberName = w [0 ]
246
+ for i in w [1 :]:
247
+ memberName += i .capitalize ()
248
+ setattr (self , memberName , self .features [op ])
249
+
250
+ self .tasks ['com' ] = self .taskCom
251
+ self .features ['com' ] = self .featureCom
252
+ self .gains ['com' ] = self .gainCom
253
+
254
+ self .features ['waist' ].selec .value = '011100'
255
+
256
+ # --- balance task --- #
257
+ (self .tasks ['balance' ], self .gains ['balance' ]) = \
258
+ createBalanceTask (robot , self , '{0}_task_balance' .format (robot .name ))
259
+
260
+
261
+ (self .featurePosture , self .featurePostureDes , self .taskPosture , self .gainPosture ) = \
262
+ createPostureTask (robot , "posture" )
263
+ self .tasks ['posture' ] = self .taskPosture
264
+ self .features ['posture' ] = self .featurePosture
265
+ self .gains ['posture' ] = self .gainPosture
266
+
267
+ initializeSignals (self , robot )
268
+
269
+ # --- create solver --- #
270
+ self .solver = Solver (robot , solverType )
271
+ self .initDefaultTasks ()
272
+
273
+ def initDefaultTasks (self ):
274
+ self .solver .sot .clear ()
275
+ self .solver .push (self .tasks ['com' ])
276
+ self .solver .push (self .tasks ['left-ankle' ])
277
+ self .solver .push (self .tasks ['right-ankle' ])
278
+
279
+
280
+
0 commit comments