Skip to content

Commit 300fe14

Browse files
Create standard application class, with basic tasks.
The initialize function becomes now deprecated, a warning is raised when it is used.
1 parent 038e2cc commit 300fe14

File tree

1 file changed

+134
-26
lines changed

1 file changed

+134
-26
lines changed

src/dynamic_graph/sot/application/velocity/precomputed_tasks.py

+134-26
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,15 @@
1414
# sot-application. If not, see <http://www.gnu.org/licenses/>.
1515

1616
#!/usr/bin/env python
17+
import warnings
1718

1819
from dynamic_graph.sot.core.feature_position import FeaturePosition
1920
from dynamic_graph.sot.core import FeatureGeneric, FeatureJointLimits, Task, \
2021
JointLimitator, SOT
22+
from dynamic_graph.sot.core.matrix_util import matrixToTuple
2123
from dynamic_graph import plug
24+
from dynamic_graph.sot.core import GainAdaptive
25+
from numpy import identity
2226

2327
class Solver:
2428

@@ -61,21 +65,21 @@ def remove (self, task):
6165
def __str__ (self):
6266
return self.sot.display ()
6367

64-
def initializeSignals (robot):
68+
def initializeSignals (application, robot):
6569
"""
6670
For portability, make some signals accessible as attributes.
6771
"""
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
7377

7478
def createCenterOfMassFeatureAndTask(robot,
7579
featureName, featureDesName,
7680
taskName,
7781
selec = '111',
78-
gain = 1.):
82+
ingain = 1.):
7983
robot.dynamic.com.recompute(0)
8084
robot.dynamic.Jcom.recompute(0)
8185

@@ -86,16 +90,19 @@ def createCenterOfMassFeatureAndTask(robot,
8690
featureComDes = FeatureGeneric(featureDesName)
8791
featureComDes.errorIN.value = robot.dynamic.com.value
8892
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)
93100

94101
def createOperationalPointFeatureAndTask(robot,
95102
operationalPointName,
96103
featureName,
97104
taskName,
98-
gain = .2):
105+
ingain = .2):
99106
jacobianName = 'J{0}'.format(operationalPointName)
100107
robot.dynamic.signal(operationalPointName).recompute(0)
101108
robot.dynamic.signal(jacobianName).recompute(0)
@@ -106,21 +113,46 @@ def createOperationalPointFeatureAndTask(robot,
106113
robot.dynamic.signal(operationalPointName).value)
107114
task = Task(taskName)
108115
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)
111121

112-
def createBalanceTask (robot, taskName, gain = 1.):
122+
def createBalanceTask (robot, application, taskName, ingain = 1.):
113123
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)
119149

120150

121151
def initialize (robot, solverType=SOT):
122152
"""
123-
Tasks are stored into 'tasks' dictionary.
153+
Tasks are stored into 'tasks' dictionary.
154+
155+
WARNING: deprecated, use Application instead
124156
125157
For portability, some signals are accessible as attributes:
126158
- zmpRef: input (vector),
@@ -130,9 +162,11 @@ def initialize (robot, solverType=SOT):
130162
- comdot: input (vector) reference velocity of the center of mass
131163
132164
"""
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")
133167

134168
# --- center of mass ------------
135-
(robot.featureCom, robot.featureComDes, robot.comTask) = \
169+
(robot.featureCom, robot.featureComDes, robot.comTask, robot.gainCom) = \
136170
createCenterOfMassFeatureAndTask(robot,
137171
'{0}_feature_com'.format(robot.name),
138172
'{0}_feature_ref_com'.format(robot.name),
@@ -141,8 +175,9 @@ def initialize (robot, solverType=SOT):
141175
# --- operational points tasks -----
142176
robot.features = dict()
143177
robot.tasks = dict()
178+
robot.gains = dict()
144179
for op in robot.OperationalPoints:
145-
(robot.features[op], robot.tasks[op]) = \
180+
(robot.features[op], robot.tasks[op], robot.gains[op]) = \
146181
createOperationalPointFeatureAndTask(robot,
147182
op, '{0}_feature_{1}'.format(robot.name, op),
148183
'{0}_task_{1}'.format(robot.name, op))
@@ -153,13 +188,14 @@ def initialize (robot, solverType=SOT):
153188
memberName += i.capitalize()
154189
setattr(robot, memberName, robot.features[op])
155190
robot.tasks ['com'] = robot.comTask
191+
robot.gains ['com'] = robot.gainCom
156192
robot.waist.selec.value = '011100'
157193

158194
# --- 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))
161197

162-
initializeSignals (robot)
198+
initializeSignals (robot, robot)
163199

164200
# --- create solver --- #
165201
solver = Solver (robot, solverType)
@@ -170,3 +206,75 @@ def initialize (robot, solverType=SOT):
170206
solver.push (robot.tasks ['right-ankle'])
171207

172208
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

Comments
 (0)