4 from dynamic_graph
import plug
5 from dynamic_graph.sot.core.madgwickahrs
import MadgwickAHRS
6 from dynamic_graph.sot.core.operator
import Mix_of_vector, Selec_of_vector
7 from dynamic_graph.sot.core.parameter_server
import ParameterServer
8 from dynamic_graph.sot_talos_balance.admittance_controller_end_effector
import (
9 AdmittanceControllerEndEffector,
11 from dynamic_graph.sot_talos_balance.ankle_admittance_controller
import (
12 AnkleAdmittanceController,
14 from dynamic_graph.sot_talos_balance.com_admittance_controller
import (
15 ComAdmittanceController,
17 from dynamic_graph.sot_talos_balance.dcm_com_controller
import DcmComController
18 from dynamic_graph.sot_talos_balance.dcm_controller
import DcmController
19 from dynamic_graph.sot_talos_balance.dcm_estimator
import DcmEstimator
20 from dynamic_graph.sot_talos_balance.distribute_wrench
import DistributeWrench
21 from dynamic_graph.sot_talos_balance.dummy_dcm_estimator
import DummyDcmEstimator
22 from dynamic_graph.sot_talos_balance.example
import Example
23 from dynamic_graph.sot_talos_balance.ft_calibration
import FtCalibration
24 from dynamic_graph.sot_talos_balance.ft_wrist_calibration
import FtWristCalibration
25 from dynamic_graph.sot_talos_balance.hip_flexibility_compensation
import (
26 HipFlexibilityCompensation,
28 from dynamic_graph.sot_talos_balance.joint_position_controller
import (
29 JointPositionController,
31 from dynamic_graph.sot_talos_balance.nd_trajectory_generator
import (
32 NdTrajectoryGenerator,
34 from dynamic_graph.sot_talos_balance.qualisys_client
import QualisysClient
35 from dynamic_graph.sot_talos_balance.simple_admittance_controller
import (
36 SimpleAdmittanceController,
38 from dynamic_graph.sot_talos_balance.simple_distribute_wrench
import (
39 SimpleDistributeWrench,
41 from dynamic_graph.sot_talos_balance.simple_zmp_estimator
import SimpleZmpEstimator
42 from dynamic_graph.sot_talos_balance.talos_base_estimator
import TalosBaseEstimator
43 from dynamic_graph.sot_talos_balance.talos_control_manager
import TalosControlManager
46 from dynamic_graph.sot_talos_balance.utils
import filter_utils
47 from dynamic_graph.sot_talos_balance.utils.sot_utils
import Bunch
48 from dynamic_graph.tracer_real_time
import TracerRealTime
54 mocap = QualisysClient(
"mocap")
55 mocap.setMocapIPAdress(address)
62 rx = np.arctan2(R[2, 1], R[2, 2])
63 ry = np.arctan2(-R[2, 0], np.sqrt(R[2, 1] * R[2, 1] + R[2, 2] * R[2, 2]))
64 rz = np.arctan2(R[1, 0], R[0, 0])
71 mix_of_vector = Mix_of_vector(
"mix " + str(n_in) +
"-" + str(n_out))
73 mix_of_vector.setSignalNumber(3)
76 mix_of_vector.addSelec(1, 0, n_diff)
77 mix_of_vector.addSelec(2, n_diff, n_in)
79 mix_of_vector.default.value = [0.0] * n_out
80 mix_of_vector.signal(
"sin1").value = [0.0] * n_diff
81 mix_of_vector.signal(
"sin2").value = [2.0] * n_in
87 trajGen = NdTrajectoryGenerator(name)
88 trajGen.initial_value.value = [init_value]
89 trajGen.trigger.value = 1
95 jtg = NdTrajectoryGenerator(
"jtg")
96 jtg.initial_value.value = robot.device.state.value[6:]
98 jtg.init(dt, N_JOINTS)
103 N_CONFIG = N_JOINTS + 6
104 jtg = NdTrajectoryGenerator(
"jtg")
105 jtg.initial_value.value = robot.device.state.value
106 jtg.trigger.value = 1
107 jtg.init(dt, N_CONFIG)
112 N_CONFIG = N_JOINTS + 6
113 jtg = NdTrajectoryGenerator(
"torqueTrajGen")
114 jtg.initial_value.value = [0.0] * N_CONFIG
115 jtg.trigger.value = 1
116 jtg.init(dt, N_CONFIG)
121 comTrajGen = NdTrajectoryGenerator(
"comTrajGen")
122 comTrajGen.initial_value.value = robot.dynamic.com.value
123 comTrajGen.trigger.value = 1
124 comTrajGen.init(dt, 3)
129 comTrajGen = NdTrajectoryGenerator(
"zmpTrajGen")
130 zmp = list(robot.dynamic.com.value)
132 comTrajGen.initial_value.value = np.array(zmp)
133 comTrajGen.trigger.value = 1
134 comTrajGen.init(dt, 3)
139 trajGen = NdTrajectoryGenerator(signal_name +
"PosTrajGen")
141 M = robot.dynamic.signal(signal_name).value
142 v = [M[i][3]
for i
in range(3)]
143 trajGen.initial_value.value = v
145 trajGen.trigger.value = 1
151 trajGen = NdTrajectoryGenerator(signal_name +
"OrientationTrajGen")
153 M = robot.dynamic.signal(signal_name).value
155 trajGen.initial_value.value = np.array(v)
157 trajGen.trigger.value = 1
163 trajGen = NdTrajectoryGenerator(signal_name +
"TrajGen")
165 M = robot.dynamic.signal(signal_name).value
166 pos = [M[i][3]
for i
in range(3)]
169 trajGen.initial_value.value = np.array(v)
171 trajGen.trigger.value = 1
177 controller = JointPositionController(
"posctrl")
178 controller.Kp.value = Kp
183 timeStep = robot.timeStep
184 controller = AdmittanceControllerEndEffector(name)
187 if endEffector ==
"rightWrist":
188 plug(robot.forceCalibrator.rightWristForceOut, controller.force)
189 elif endEffector ==
"leftWrist":
190 plug(robot.forceCalibrator.leftWristForceOut, controller.force)
193 "Error in create_end_effector_admittance_controller : end \
197 plug(robot.e2q.quaternion, controller.q)
199 controller.Kp.value = [0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
200 controller.Kd.value = [0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
201 controller.w_forceDes.value = [0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
202 controller.dqSaturation.value = [0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
204 if endEffector ==
"rightWrist":
205 controller.init(timeStep,
"wrist_right_ft_link",
"arm_right_7_joint")
206 elif endEffector ==
"leftWrist":
207 controller.init(timeStep,
"wrist_left_ft_link",
"arm_left_7_joint")
210 "Error in create_end_effector_admittance_controller : end \
218 controller = SimpleAdmittanceController(
"jadmctrl")
219 controller.Kp.value = Kp
221 robot.stateselec = Selec_of_vector(
"state_selec")
222 robot.stateselec.selec(joint + 6, joint + 7)
223 plug(robot.device.state, robot.stateselec.sin)
224 plug(robot.stateselec.sout, controller.state)
226 robot.tauselec = Selec_of_vector(
"tau_selec")
227 robot.tauselec.selec(joint, joint + 1)
228 if filter
and hasattr(robot,
"device_filters"):
229 plug(robot.device_filters.torque_filter.x_filtered, robot.tauselec.sin)
231 plug(robot.device.ptorque, robot.tauselec.sin)
232 plug(robot.tauselec.sout, controller.tau)
234 controller.tauDes.value = [0.0]
235 controller.init(dt, 1)
236 controller.setPosition([robot.device.state.value[joint + 6]])
241 timeStep = robot.timeStep
242 hipComp = HipFlexibilityCompensation(
"hipFlexCompensation")
243 hipComp.K_l.value = conf.flexibility_left
244 hipComp.K_r.value = conf.flexibility_right
245 hipComp.q_des.value = robot.dynamic.getDimension() * [0.0]
246 plug(robot.device.ptorque, hipComp.tau)
247 hipComp.init(timeStep, robot_name)
249 hipComp.setAngularSaturation(conf.angular_saturation)
250 hipComp.setRateLimiter(conf.rate_limiter)
251 hipComp.setTorqueLowPassFilterFrequency(conf.torque_low_pass_freq)
256 controller = AnkleAdmittanceController(name)
260 plug(robot.ftc.right_foot_force_out, controller.wrench)
262 plug(robot.ftc.left_foot_force_out, controller.wrench)
264 print(
"Error in create_ankle_admittance_controller : side unknown")
266 controller.gainsXY.value = gains
268 plug(robot.wrenchDistributor.copRight, controller.pRef)
270 plug(robot.wrenchDistributor.copLeft, controller.pRef)
272 print(
"Error in create_ankle_admittance_controller : side unknown")
280 robot.pselec = Selec_of_vector(
"pselec")
281 robot.pselec.selec(6, 6 + N_JOINTS)
282 plug(robot.device.state, robot.pselec.sin)
284 robot.vselec = Selec_of_vector(
"vselec")
285 robot.vselec.selec(6, 6 + N_JOINTS)
286 plug(robot.device.velocity, robot.vselec.sin)
289 filters.joints_kin = filter_utils.create_chebi1_checby2_series_filter(
290 "joints_kin", dt, N_JOINTS
292 filters.ft_RF_filter = filter_utils.create_butter_lp_filter_Wn_04_N_2(
293 "ft_RF_filter", dt, 6
295 filters.ft_LF_filter = filter_utils.create_butter_lp_filter_Wn_04_N_2(
296 "ft_LF_filter", dt, 6
298 filters.ft_RH_filter = filter_utils.create_butter_lp_filter_Wn_04_N_2(
299 "ft_RH_filter", dt, 6
301 filters.ft_LH_filter = filter_utils.create_butter_lp_filter_Wn_04_N_2(
302 "ft_LH_filter", dt, 6
304 filters.torque_filter = filter_utils.create_chebi1_checby2_series_filter(
305 "ptorque_filter", dt, N_JOINTS
307 filters.acc_filter = filter_utils.create_chebi1_checby2_series_filter(
310 filters.gyro_filter = filter_utils.create_chebi1_checby2_series_filter(
313 filters.vel_filter = filter_utils.create_butter_lp_filter_Wn_04_N_2(
314 "vel_filter", dt, N_JOINTS
318 plug(robot.device.joint_angles, filters.joints_kin.x)
319 plug(robot.device.forceRLEG, filters.ft_RF_filter.x)
320 plug(robot.device.forceLLEG, filters.ft_LF_filter.x)
321 plug(robot.device.forceRARM, filters.ft_RH_filter.x)
322 plug(robot.device.forceLARM, filters.ft_LH_filter.x)
323 plug(robot.device.ptorque, filters.torque_filter.x)
324 plug(robot.vselec.sout, filters.vel_filter.x)
326 plug(robot.device.accelerometer, filters.acc_filter.x)
327 plug(robot.device.gyrometer, filters.gyro_filter.x)
334 be_filters.test = filter_utils.create_chebi1_checby2_series_filter(
335 "test_filter", dt, N_JOINTS
337 plug(robot.base_estimator.q, be_filters.test.x)
342 ctrl_manager = TalosControlManager(
"ctrl_man")
343 ctrl_manager.add_commands()
344 ctrl_manager.add_signals()
345 ctrl_manager.init(dt, robot_name)
346 ctrl_manager.u_max.value = np.array(conf.NJ * (conf.CTRL_MAX,))
353 base_estimator = TalosBaseEstimator(
"base_estimator")
354 base_estimator.init(dt, robot_name)
357 plug(robot.device.joint_angles, base_estimator.joint_positions)
358 plug(robot.device_filters.ft_LF_filter.x_filtered, base_estimator.forceLLEG)
359 plug(robot.device_filters.ft_RF_filter.x_filtered, base_estimator.forceRLEG)
360 plug(robot.device_filters.ft_LF_filter.dx, base_estimator.dforceLLEG)
361 plug(robot.device_filters.ft_RF_filter.dx, base_estimator.dforceRLEG)
363 plug(robot.vselec.sout, base_estimator.joint_velocities)
365 plug(robot.imu_filters.imu_quat, base_estimator.imu_quaternion)
366 plug(robot.device_filters.gyro_filter.x_filtered, base_estimator.gyroscope)
367 plug(robot.device_filters.acc_filter.x_filtered, base_estimator.accelerometer)
368 base_estimator.K_fb_feet_poses.value = conf.K_fb_feet_poses
371 base_estimator.set_imu_weight(conf.w_imu)
372 base_estimator.set_stiffness_right_foot(np.array(conf.K))
373 base_estimator.set_stiffness_left_foot(np.array(conf.K))
374 base_estimator.set_zmp_std_dev_right_foot(conf.std_dev_zmp)
375 base_estimator.set_zmp_std_dev_left_foot(conf.std_dev_zmp)
376 base_estimator.set_normal_force_std_dev_right_foot(conf.std_dev_fz)
377 base_estimator.set_normal_force_std_dev_left_foot(conf.std_dev_fz)
378 base_estimator.set_zmp_margin_right_foot(conf.zmp_margin)
379 base_estimator.set_zmp_margin_left_foot(conf.zmp_margin)
380 base_estimator.set_normal_force_margin_right_foot(conf.normal_force_margin)
381 base_estimator.set_normal_force_margin_left_foot(conf.normal_force_margin)
382 base_estimator.set_right_foot_sizes(np.array(conf.RIGHT_FOOT_SIZES))
383 base_estimator.set_left_foot_sizes(np.array(conf.LEFT_FOOT_SIZES))
385 return base_estimator
389 imu_filter = MadgwickAHRS(
"imu_filter")
391 imu_filter.set_imu_quat(np.array([0.0, 1.0, 0.0, 0.0]))
392 imu_filter.setBeta(1e-3)
394 robot.device_filters.acc_filter.x_filtered, imu_filter.accelerometer
397 robot.device_filters.gyro_filter.x_filtered, imu_filter.gyroscope
404 Add a signal to a tracer
406 signal =
"{0}.{1}".format(entity.name, signalName)
407 filename =
"{0}-{1}".format(entity.name, signalName)
408 tracer.add(signal, filename)
418 tracer = TracerRealTime(tracer_name)
419 tracer.setBufferSize(80 * (2**20))
420 tracer.open(
"/tmp",
"dg_",
".dat")
421 robot.device.after.addSignal(
"{0}.triger".format(tracer.name))
422 if outputs
is not None:
447 from dynamic_graph.ros
import RosPublish
449 rospub = RosPublish(name)
450 robot.device.after.addSignal(rospub.name +
".trigger")
454 def create_topic(rospub, entity, signalName, robot=None, data_type="vector"):
456 if not entity.hasSignal(signalName):
457 raise AttributeError(
458 "Entity %s does not have signal %s" % (entity.name, signalName)
460 rospub_signalName =
"{0}_{1}".format(entity.name, signalName)
461 topicname =
"/sot/{0}/{1}".format(entity.name, signalName)
462 rospub.add(data_type, rospub_signalName, topicname)
463 plug(entity.signal(signalName), rospub.signal(rospub_signalName))
464 if robot
is not None:
465 robot.device.after.addSignal(
"{0}.{1}".format(entity.name, signalName))
469 from math
import sqrt
471 estimator = DummyDcmEstimator(
"dummy")
472 robot.dynamic.com.recompute(0)
473 mass = robot.dynamic.data.mass[0]
474 h = robot.dynamic.com.value[2]
478 estimator.mass.value = mass
479 estimator.omega.value = omega
480 plug(robot.dynamic.com, estimator.com)
481 plug(robot.dynamic.momenta, estimator.momenta)
487 from math
import sqrt
489 estimator = DummyDcmEstimator(
"dummy")
490 robot.dynamic.com.recompute(0)
491 h = robot.dynamic.com.value[2]
495 estimator.mass.value = 1.0
496 estimator.omega.value = omega
497 plug(robot.cdc_estimator.c, estimator.com)
498 plug(robot.cdc_estimator.dc, estimator.momenta)
504 controller = ComAdmittanceController(
"comAdmCtrl")
505 controller.Kp.value = Kp
506 plug(robot.dynamic.zmp, controller.zmp)
507 robot.dynamic.zmp.recompute(0)
508 controller.zmpDes.value = robot.dynamic.zmp.value
509 controller.ddcomDes.value = [0.0, 0.0, 0.0]
512 robot.dynamic.com.recompute(0)
513 controller.setState(robot.dynamic.com.value, [0.0, 0.0, 0.0])
518 from math
import sqrt
520 controller = DcmController(
"dcmCtrl")
521 robot.dynamic.com.recompute(0)
522 mass = robot.dynamic.data.mass[0]
523 h = robot.dynamic.com.value[2]
527 controller.Kp.value = Kp
528 controller.Ki.value = Ki
529 controller.decayFactor.value = 0.2
530 controller.mass.value = mass
531 controller.omega.value = omega
533 plug(robot.dynamic.com, controller.com)
534 plug(dcmSignal, controller.dcm)
536 robot.dynamic.zmp.recompute(0)
537 controller.zmpDes.value = robot.dynamic.zmp.value
538 controller.dcmDes.value = robot.dynamic.zmp.value
545 from math
import sqrt
547 controller = DcmComController(
"dcmComCtrl")
548 robot.dynamic.com.recompute(0)
549 mass = robot.dynamic.data.mass[0]
550 h = robot.dynamic.com.value[2]
554 controller.Kp.value = Kp
555 controller.Ki.value = Ki
556 controller.decayFactor.value = 0.2
557 controller.mass.value = mass
558 controller.omega.value = omega
560 controller.ddcomDes.value = [0.0, 0.0, 0.0]
562 plug(dcmSignal, controller.dcm)
564 robot.dynamic.com.recompute(0)
565 controller.comDes.value = robot.dynamic.com.value
566 controller.dcmDes.value = (
567 robot.dynamic.com.value[0],
568 robot.dynamic.com.value[1],
579 param_server.init(dt, conf.urdfFileName, robot_name)
582 for key
in conf.mapJointNameToID:
583 param_server.setNameToId(key, conf.mapJointNameToID[key])
586 for key
in conf.mapJointLimits:
587 param_server.setJointLimitsFromId(
588 key, conf.mapJointLimits[key][0], conf.mapJointLimits[key][1]
592 for key
in conf.mapForceIdToForceLimits:
593 param_server.setForceLimitsFromId(
595 np.array(conf.mapForceIdToForceLimits[key][0]),
596 np.array(conf.mapForceIdToForceLimits[key][1]),
600 for key
in conf.mapNameToForceId:
601 param_server.setForceNameToForceId(key, conf.mapNameToForceId[key])
604 param_server.setJointsUrdfToSot(np.array(conf.urdftosot))
607 for key
in conf.footFrameNames:
608 param_server.setFootFrameName(key, conf.footFrameNames[key])
611 param_server.setImuJointName(conf.ImuJointName)
613 param_server.setRightFootForceSensorXYZ(np.array(conf.rightFootSensorXYZ))
614 param_server.setRightFootSoleXYZ(np.array(conf.rightFootSoleXYZ))
620 param_server = ParameterServer(
"param_server")
625 example = Example(
"example")
626 example.firstAddend.value = firstAdd
627 example.secondAddend.value = secondAdd
628 example.init(robot_name)
633 dcm_estimator = DcmEstimator(
"dcm_estimator")
634 dcm_estimator.init(dt, robot_name)
635 plug(robot.base_estimator.q, dcm_estimator.q)
636 plug(robot.base_estimator.v, dcm_estimator.v)
641 distribute = DistributeWrench(
"distribute")
643 distribute.phase.value = 0
644 distribute.rho.value = 0.5
646 distribute.setMinPressure(conf.minPressure)
647 distribute.frictionCoefficient.value = conf.frictionCoefficient
648 distribute.wSum.value = conf.wSum
649 distribute.wNorm.value = conf.wNorm
650 distribute.wRatio.value = conf.wRatio
651 distribute.wAnkle.value = np.array(conf.wAnkle)
653 distribute.set_right_foot_sizes(np.array(conf.RIGHT_FOOT_SIZES))
654 distribute.set_left_foot_sizes(np.array(conf.LEFT_FOOT_SIZES))
660 distribute = SimpleDistributeWrench(name)
662 distribute.phase.value = 0
663 distribute.rho.value = 0.5
669 estimator = SimpleZmpEstimator(
"zmpEst")
670 plug(robot.dynamic.LF, estimator.poseLeft)
671 plug(robot.dynamic.RF, estimator.poseRight)
672 if filter
and hasattr(robot,
"device_filters"):
673 plug(robot.device_filters.ft_LF_filter.x_filtered, estimator.wrenchLeft)
674 plug(robot.device_filters.ft_RF_filter.x_filtered, estimator.wrenchRight)
676 plug(robot.device.forceLLEG, estimator.wrenchLeft)
677 plug(robot.device.forceRLEG, estimator.wrenchRight)
684 ftc = FtCalibration(
"ftc")
686 ftc.setRightFootWeight(conf.rfw)
687 ftc.setLeftFootWeight(conf.lfw)
688 plug(robot.device_filters.ft_RF_filter.x_filtered, ftc.right_foot_force_in)
689 plug(robot.device_filters.ft_LF_filter.x_filtered, ftc.left_foot_force_in)
694 forceCalibrator = FtWristCalibration(
"forceCalibrator")
695 forceCalibrator.init(robot.name)
696 forceCalibrator.setRightHandConf(endEffectorWeight, rightOC)
697 forceCalibrator.setLeftHandConf(endEffectorWeight, leftOC)
698 forceCalibrator.setRemoveWeight(
True)
699 plug(robot.e2q.quaternion, forceCalibrator.q)
701 robot.device_filters.ft_RH_filter.x_filtered, forceCalibrator.rightWristForceIn
703 plug(robot.device_filters.ft_LH_filter.x_filtered, forceCalibrator.leftWristForceIn)
704 return forceCalibrator
708 robot.triggerTrajGen.sin.value = 1.0
if on
else 0.0
712 val = robot.triggerTrajGen.sin.value
718 raise RuntimeError(
"Bad trigger")
723 print(
"Warning: trigger is still active. Not loading folder")
725 if folder
is not None:
726 robot.comTrajGen.playTrajectoryFile(folder +
"CoM.dat")
727 robot.lfTrajGen.playTrajectoryFile(folder +
"LeftFoot.dat")
728 robot.rfTrajGen.playTrajectoryFile(folder +
"RightFoot.dat")
730 robot.zmpTrajGen.playTrajectoryFile(folder +
"ZMP.dat")
731 robot.waistTrajGen.playTrajectoryFile(folder +
"WaistOrientation.dat")
733 robot.rhoTrajGen.playTrajectoryFile(folder +
"Rho.dat")
734 except AttributeError:
737 robot.phaseTrajGen.playTrajectoryFile(folder +
"Phase.dat")
738 except AttributeError:
741 robot.torqueTrajGen.playTrajectoryFile(folder +
"Torques.dat")
742 except AttributeError: