sot-talos-balance  2.0.5
Collection of dynamic-graph entities aimed at implementing balance control on talos.
appli_dcmZmpControl.py
Go to the documentation of this file.
1 # flake8: noqa
2 from math import sqrt
3 
4 from dynamic_graph import plug
5 from dynamic_graph.sot.core import SOT, Derivator_of_Vector, FeaturePosture, Task
6 from dynamic_graph.sot.core.matrix_util import matrixToTuple
7 from dynamic_graph.sot.core.meta_tasks_kine import (
8  MetaTaskKine6d,
9  MetaTaskKineCom,
10  gotoNd,
11 )
12 from dynamic_graph.tracer_real_time import TracerRealTime
13 
14 import dynamic_graph.sot_talos_balance.talos.parameter_server_conf as param_server_conf
16 
17 robot.timeStep = robot.device.getTimeStep()
18 dt = robot.timeStep
19 
20 # -------------------------- DESIRED TRAJECTORY --------------------------
21 
22 # --- Desired values
23 robot.dynamic.com.recompute(0)
24 # comDes = robot.dynamic.com.value
25 comDes = list(robot.dynamic.com.value)
26 comDes[0] += 0.001
27 comDes[1] += 0.001
28 comDes = tuple(comDes)
29 dcmDes = comDes
30 zmpDes = comDes[:2] + (0.0,)
31 ddcomDes = (0.0, 0.0, 0.0)
32 
33 # --- Pendulum parameters
34 mass = robot.dynamic.data.mass[0]
35 h = robot.dynamic.com.value[2]
36 g = 9.81
37 omega = sqrt(g / h)
38 
39 # -------------------------- ESTIMATION --------------------------
40 
41 # --- General Estimation
42 # robot.param_server = create_parameter_server(param_server_conf,dt)
43 # robot_name='robot'
44 # cdc_estimator = DcmEstimator('dcm_estimator')
45 # cdc_estimator.init(dt, robot_name)
46 # plug(robot.device.state, cdc_estimator.q)
47 # plug(robot.device.velocity, cdc_estimator.v)
48 # robot.cdc_estimator = cdc_estimator # cdc_estimator.c == robot.dynamic.com
49 robot.cdc_estimator = robot.dynamic
50 
51 # --- DCM Estimation
52 estimator = DummyDcmEstimator("dummy")
53 estimator.omega.value = omega
54 # estimator.mass.value = 1.0
55 # plug(robot.cdc_estimator.c, estimator.com)
56 # plug(robot.cdc_estimator.dc,estimator.momenta)
57 estimator.mass.value = mass
58 plug(robot.cdc_estimator.com, estimator.com)
59 plug(robot.cdc_estimator.momenta, estimator.momenta)
60 estimator.init()
61 robot.estimator = estimator
62 
63 # --- filters
64 filters = Bunch()
65 filters.ft_RF_filter = create_butter_lp_filter_Wn_04_N_2("ft_RF_filter", dt, 6)
66 filters.ft_LF_filter = create_butter_lp_filter_Wn_04_N_2("ft_LF_filter", dt, 6)
67 plug(robot.device.forceRLEG, filters.ft_RF_filter.x)
68 plug(robot.device.forceLLEG, filters.ft_LF_filter.x)
69 robot.device_filters = filters
70 
71 # --- ZMP estimation
72 zmp_estimator = SimpleZmpEstimator("zmpEst")
73 robot.dynamic.createOpPoint("sole_LF", "left_sole_link")
74 robot.dynamic.createOpPoint("sole_RF", "right_sole_link")
75 plug(robot.dynamic.sole_LF, zmp_estimator.poseLeft)
76 plug(robot.dynamic.sole_RF, zmp_estimator.poseRight)
77 plug(robot.device_filters.ft_LF_filter.x_filtered, zmp_estimator.wrenchLeft)
78 plug(robot.device_filters.ft_RF_filter.x_filtered, zmp_estimator.wrenchRight)
79 # plug(robot.device.forceLLEG,zmp_estimator.wrenchLeft)
80 # plug(robot.device.forceRLEG,zmp_estimator.wrenchRight)
81 zmp_estimator.init()
82 robot.zmp_estimator = zmp_estimator
83 
84 # -------------------------- ADMITTANCE CONTROL --------------------------
85 
86 # --- DCM controller
87 Kp_dcm = [8.0, 8.0, 8.0]
88 Ki_dcm = [0.0, 0.0, 0.0] # zero (to be set later)
89 gamma_dcm = 0.2
90 
91 dcm_controller = DcmController("dcmCtrl")
92 
93 dcm_controller.Kp.value = Kp_dcm
94 dcm_controller.Ki.value = Ki_dcm
95 dcm_controller.decayFactor.value = gamma_dcm
96 dcm_controller.mass.value = mass
97 dcm_controller.omega.value = omega
98 
99 plug(robot.cdc_estimator.com, dcm_controller.com)
100 plug(robot.estimator.dcm, dcm_controller.dcm)
101 
102 dcm_controller.zmpDes.value = zmpDes # plug a signal here
103 dcm_controller.dcmDes.value = dcmDes # plug a signal here
104 
105 dcm_controller.init(dt)
106 
107 robot.dcm_control = dcm_controller
108 
109 Ki_dcm = [0.0, 0.0, 0.0] # this value is employed later
110 
111 # --- CoM admittance controller
112 Kp_adm = [0.0, 0.0, 0.0] # zero (to be set later)
113 
114 com_admittance_control = ComAdmittanceController("comAdmCtrl")
115 com_admittance_control.Kp.value = Kp_adm
116 plug(robot.dynamic.zmp, com_admittance_control.zmp)
117 com_admittance_control.zmpDes.value = (
118  zmpDes # should be plugged to robot.dcm_control.zmpRef
119 )
120 com_admittance_control.ddcomDes.value = ddcomDes # plug a signal here
121 
122 com_admittance_control.init(dt)
123 com_admittance_control.setState(comDes, [0.0, 0.0, 0.0])
124 
125 robot.com_admittance_control = com_admittance_control
126 
127 Kp_adm = [8.0, 8.0, 0.0] # this value is employed later
128 
129 # -------------------------- SOT CONTROL --------------------------
130 
131 # --- Upper body
132 robot.taskUpperBody = Task("task_upper_body")
133 robot.taskUpperBody.feature = FeaturePosture("feature_upper_body")
134 
135 q = list(robot.dynamic.position.value)
136 robot.taskUpperBody.feature.state.value = q
137 robot.taskUpperBody.feature.posture.value = q
138 
139 # robotDim = robot.dynamic.getDimension() # 38
140 robot.taskUpperBody.feature.selectDof(18, True)
141 robot.taskUpperBody.feature.selectDof(19, True)
142 robot.taskUpperBody.feature.selectDof(20, True)
143 robot.taskUpperBody.feature.selectDof(21, True)
144 robot.taskUpperBody.feature.selectDof(22, True)
145 robot.taskUpperBody.feature.selectDof(23, True)
146 robot.taskUpperBody.feature.selectDof(24, True)
147 robot.taskUpperBody.feature.selectDof(25, True)
148 robot.taskUpperBody.feature.selectDof(26, True)
149 robot.taskUpperBody.feature.selectDof(27, True)
150 robot.taskUpperBody.feature.selectDof(28, True)
151 robot.taskUpperBody.feature.selectDof(29, True)
152 robot.taskUpperBody.feature.selectDof(30, True)
153 robot.taskUpperBody.feature.selectDof(31, True)
154 robot.taskUpperBody.feature.selectDof(32, True)
155 robot.taskUpperBody.feature.selectDof(33, True)
156 robot.taskUpperBody.feature.selectDof(34, True)
157 robot.taskUpperBody.feature.selectDof(35, True)
158 robot.taskUpperBody.feature.selectDof(36, True)
159 robot.taskUpperBody.feature.selectDof(37, True)
160 
161 robot.taskUpperBody.controlGain.value = 100.0
162 robot.taskUpperBody.add(robot.taskUpperBody.feature.name)
163 plug(robot.dynamic.position, robot.taskUpperBody.feature.state)
164 
165 # --- CONTACTS
166 # define contactLF and contactRF
167 robot.contactLF = MetaTaskKine6d(
168  "contactLF", robot.dynamic, "LF", robot.OperationalPointsMap["left-ankle"]
169 )
170 robot.contactLF.feature.frame("desired")
171 robot.contactLF.gain.setConstant(300)
172 robot.contactLF.keep()
173 locals()["contactLF"] = robot.contactLF
174 
175 robot.contactRF = MetaTaskKine6d(
176  "contactRF", robot.dynamic, "RF", robot.OperationalPointsMap["right-ankle"]
177 )
178 robot.contactRF.feature.frame("desired")
179 robot.contactRF.gain.setConstant(300)
180 robot.contactRF.keep()
181 locals()["contactRF"] = robot.contactRF
182 
183 # --- COM
184 robot.taskCom = MetaTaskKineCom(robot.dynamic)
185 plug(robot.com_admittance_control.comRef, robot.taskCom.featureDes.errorIN)
186 plug(robot.com_admittance_control.dcomRef, robot.taskCom.featureDes.errordotIN)
187 robot.taskCom.task.controlGain.value = 0
188 robot.taskCom.task.setWithDerivative(True)
189 
190 # --- Waist
191 robot.keepWaist = MetaTaskKine6d(
192  "keepWaist", robot.dynamic, "WT", robot.OperationalPointsMap["waist"]
193 )
194 robot.keepWaist.feature.frame("desired")
195 robot.keepWaist.gain.setConstant(300)
196 robot.keepWaist.keep()
197 robot.keepWaist.feature.selec.value = "111000"
198 locals()["keepWaist"] = robot.keepWaist
199 
200 # # --- Posture
201 # robot.taskPos = Task ('task_pos')
202 # robot.taskPos.feature = FeaturePosture('feature_pos')
203 #
204 # q = list(robot.dynamic.position.value)
205 # robot.taskPos.feature.state.value = q
206 # robot.taskPos.feature.posture.value = q
207 
208 # robotDim = robot.dynamic.getDimension() # 38
209 # robot.taskPos.feature.selectDof(6,True)
210 # robot.taskPos.feature.selectDof(7,True)
211 # robot.taskPos.feature.selectDof(8,True)
212 # robot.taskPos.feature.selectDof(9,True)
213 # robot.taskPos.feature.selectDof(10,True)
214 # robot.taskPos.feature.selectDof(11,True)
215 # robot.taskPos.feature.selectDof(12,True)
216 # robot.taskPos.feature.selectDof(13,True)
217 # robot.taskPos.feature.selectDof(14,True)
218 # robot.taskPos.feature.selectDof(15,True)
219 # robot.taskPos.feature.selectDof(16,True)
220 # robot.taskPos.feature.selectDof(17,True)
221 # robot.taskPos.feature.selectDof(18,True)
222 # robot.taskPos.feature.selectDof(19,True)
223 # robot.taskPos.feature.selectDof(20,True)
224 # robot.taskPos.feature.selectDof(21,True)
225 # robot.taskPos.feature.selectDof(22,True)
226 # robot.taskPos.feature.selectDof(23,True)
227 # robot.taskPos.feature.selectDof(24,True)
228 # robot.taskPos.feature.selectDof(25,True)
229 # robot.taskPos.feature.selectDof(26,True)
230 # robot.taskPos.feature.selectDof(27,True)
231 # robot.taskPos.feature.selectDof(28,True)
232 # robot.taskPos.feature.selectDof(29,True)
233 # robot.taskPos.feature.selectDof(30,True)
234 # robot.taskPos.feature.selectDof(31,True)
235 # robot.taskPos.feature.selectDof(32,True)
236 # robot.taskPos.feature.selectDof(33,True)
237 # robot.taskPos.feature.selectDof(34,True)
238 # robot.taskPos.feature.selectDof(35,True)
239 # robot.taskPos.feature.selectDof(36,True)
240 # robot.taskPos.feature.selectDof(37,True)
241 
242 # robot.taskPos.controlGain.value = 100.0
243 # robot.taskPos.add(robot.taskPos.feature.name)
244 # plug(robot.dynamic.position, robot.taskPos.feature.state)
245 
246 # --- SOT solver
247 robot.sot = SOT("sot")
248 robot.sot.setSize(robot.dynamic.getDimension())
249 plug(robot.sot.control, robot.device.control)
250 
251 robot.sot.push(robot.taskUpperBody.name)
252 robot.sot.push(robot.contactRF.task.name)
253 robot.sot.push(robot.contactLF.task.name)
254 robot.sot.push(robot.taskCom.task.name)
255 robot.sot.push(robot.keepWaist.task.name)
256 # robot.sot.push(robot.taskPos.name)
257 robot.device.control.recompute(0)
258 
259 # --- Fix robot.dynamic inputs
260 plug(robot.device.velocity, robot.dynamic.velocity)
261 robot.dvdt = Derivator_of_Vector("dv_dt")
262 robot.dvdt.dt.value = dt
263 plug(robot.device.velocity, robot.dvdt.sin)
264 plug(robot.dvdt.sout, robot.dynamic.acceleration)
265 
266 # -------------------------- PLOTS --------------------------
267 
268 # --- ROS PUBLISHER
269 robot.publisher = create_rospublish(robot, "robot_publisher")
270 
271 rospub_signalName = "{0}_{1}".format("fake", "comDes")
272 topicname = "/sot/{0}/{1}".format("fake", "comDes")
273 robot.publisher.add("vector", rospub_signalName, topicname)
274 plug(
275  robot.dcm_control.dcmDes, robot.publisher.signal(rospub_signalName)
276 ) # desired CoM (workaround)
277 
278 rospub_signalName = "{0}_{1}".format(robot.cdc_estimator.name, "c")
279 topicname = "/sot/{0}/{1}".format(robot.cdc_estimator.name, "c")
280 robot.publisher.add("vector", rospub_signalName, topicname)
281 plug(
282  robot.cdc_estimator.com, robot.publisher.signal(rospub_signalName)
283 ) # estimated CoM (workaround)
284 # create_topic(robot.publisher, robot.cdc_estimator, 'c', robot = robot, data_type='vector') # estimated CoM (to be modified)
285 
287  robot.publisher,
288  robot.com_admittance_control,
289  "comRef",
290  robot=robot,
291  data_type="vector",
292 ) # reference CoM
294  robot.publisher, robot.dynamic, "com", robot=robot, data_type="vector"
295 ) # resulting SOT CoM
296 
298  robot.publisher, robot.dcm_control, "dcmDes", robot=robot, data_type="vector"
299 ) # desired DCM
301  robot.publisher, robot.estimator, "dcm", robot=robot, data_type="vector"
302 ) # estimated DCM
303 
305  robot.publisher, robot.dcm_control, "zmpDes", robot=robot, data_type="vector"
306 ) # desired ZMP
308  robot.publisher, robot.dynamic, "zmp", robot=robot, data_type="vector"
309 ) # SOT ZMP
311  robot.publisher, robot.zmp_estimator, "zmp", robot=robot, data_type="vector"
312 ) # estimated ZMP
314  robot.publisher, robot.dcm_control, "zmpRef", robot=robot, data_type="vector"
315 ) # reference ZMP
316 
317 # --- TRACER
318 robot.tracer = TracerRealTime("zmp_tracer")
319 robot.tracer.setBufferSize(80 * (2**20))
320 robot.tracer.open("/tmp", "dg_", ".dat")
321 robot.device.after.addSignal("{0}.triger".format(robot.tracer.name))
322 
323 addTrace(robot.tracer, robot.dcm_control, "dcmDes") # desired CoM (workaround)
324 addTrace(robot.tracer, robot.dynamic, "com") # estimated CoM (workaround)
325 # addTrace(robot.tracer, robot.cdc_estimator, 'com') # estimated CoM (to be modified)
326 addTrace(robot.tracer, robot.com_admittance_control, "comRef") # reference CoM
327 # addTrace(robot.tracer, robot.dynamic, 'com') # resulting SOT CoM (already added)
328 
329 # addTrace(robot.tracer, robot.dcm_control, 'dcmDes') # desired DCM (already added)
330 addTrace(robot.tracer, robot.estimator, "dcm") # estimated DCM
331 
332 addTrace(robot.tracer, robot.dcm_control, "zmpDes") # desired ZMP
333 addTrace(robot.tracer, robot.zmp_estimator, "zmp") # estimated ZMP
334 addTrace(robot.tracer, robot.dcm_control, "zmpRef") # reference ZMP
335 addTrace(robot.tracer, robot.dynamic, "zmp") # SOT ZMP
336 
337 # -------------------------- SIMULATION --------------------------
338 
339 robot.tracer.start()
def addTrace(tracer, entity, signalName)
def create_topic(rospub, entity, signalName, robot=None, data_type="vector")
def create_butter_lp_filter_Wn_04_N_2(name, dt, size)
Definition: filter_utils.py:40