From bcf47aff87cbd6c4c0b468e000466e53336f53c9 Mon Sep 17 00:00:00 2001 From: Thomas Moulard <thomas.moulard@gmail.com> Date: Wed, 28 Sep 2011 11:47:54 +0200 Subject: [PATCH] Add support for additional frames storing sensors position, use it to compute HRP-2 camera positions. --- src/dynamic_graph/sot/dynamics/hrp2.py.in | 61 +++++++++++++++++++ .../sot/dynamics/humanoid_robot.py | 37 ++++++++++- 2 files changed, 97 insertions(+), 1 deletion(-) diff --git a/src/dynamic_graph/sot/dynamics/hrp2.py.in b/src/dynamic_graph/sot/dynamics/hrp2.py.in index 93e8ed2..f1ee904 100755 --- a/src/dynamic_graph/sot/dynamics/hrp2.py.in +++ b/src/dynamic_graph/sot/dynamics/hrp2.py.in @@ -14,6 +14,7 @@ # received a copy of the GNU Lesser General Public License along with # dynamic-graph. If not, see <http://www.gnu.org/licenses/>. +import numpy as np from dynamic_graph.sot import SE3, R3, SO3 from dynamic_graph.sot.core import FeaturePoint6dRelative, \ FeatureGeneric, FeatureJointLimits, Task, Constraint, GainAdaptive, SOT @@ -30,6 +31,14 @@ from dynamic_graph.sot.dynamics.humanoid_robot import AbstractHumanoidRobot hrp2_10_pkgdatarootdir = "@HRP2_10_PKGDATAROOTDIR@" hrp2_14_pkgdatarootdir = "@HRP2_14_PKGDATAROOTDIR@" +# Internal helper tool. +def matrixToTuple(M): + tmp = M.tolist() + res = [] + for i in tmp: + res.append(tuple(i)) + return tuple(res) + class Hrp2(AbstractHumanoidRobot): """ @@ -111,4 +120,56 @@ class Hrp2Laas (Hrp2): modelDir = hrp2_14_pkgdatarootdir, xmlDir = hrp2_14_pkgdatarootdir, device = None): + + # Define camera positions w.r.t gaze. + cameraBottomLeftPosition = np.matrix(( + (1., 0., 0., 0.035), + (0., 1., 0., 0.072), + (0., 0., 1., 0.075), + (0., 0., 0., 1.), + )) + cameraBottomRightPosition = np.matrix(( + (1., 0., 0., 0.035), + (0., 1., 0., -0.072), + (0., 0., 1., 0.075), + (0., 0., 0., 1.), + )) + cameraTopLeftPosition = np.matrix(( + (0.99920, 0.00120, 0.03997, 0.01), + (0.00000, 0.99955,-0.03000, 0.029), + (-0.03999, 0.02997, 0.99875, 0.145), + (0., 0., 0., 1.), + )) + cameraTopRightPosition = np.matrix(( + (0.99920, 0.00000, 0.03999, 0.01), + (0.00000, 1.00000, 0.00000, -0.029), + (-0.03999, 0.00000, 0.99920, 0.145), + (0., 0., 0., 1.), + )) + + # Frames re-orientation: + # Z = depth (increase from near to far) + # X = increase from left to right + # Y = increase from top to bottom + c1_M_c = np.matrix( + [[ 0., 0., 1., 0.], + [-1., 0., 0., 0.], + [ 0., -1., 0., 0.], + [ 0., 0., 0., 1.]]) + + for camera in [cameraBottomLeftPosition, cameraBottomRightPosition, + cameraTopLeftPosition, cameraTopRightPosition]: + camera = camera * c1_M_c + + self.AdditionalFrames.append( + ("cameraBottomLeft", matrixToTuple(cameraBottomLeftPosition), "gaze")) + self.AdditionalFrames.append( + ("cameraBottomRight", matrixToTuple(cameraBottomRightPosition), "gaze")) + self.AdditionalFrames.append( + ("cameraTopLeft", matrixToTuple(cameraTopLeftPosition), "gaze")) + self.AdditionalFrames.append( + ("cameraTopRight", matrixToTuple(cameraTopRightPosition), "gaze")) + Hrp2.__init__(self, name, modelDir, xmlDir, device, DynamicHrp2) + +__all__ = [Hrp2, Hrp2Jrl, Hrp2Laas] diff --git a/src/dynamic_graph/sot/dynamics/humanoid_robot.py b/src/dynamic_graph/sot/dynamics/humanoid_robot.py index 2aa8054..44090e4 100755 --- a/src/dynamic_graph/sot/dynamics/humanoid_robot.py +++ b/src/dynamic_graph/sot/dynamics/humanoid_robot.py @@ -15,6 +15,7 @@ # dynamic-graph. If not, see <http://www.gnu.org/licenses/>. from dynamic_graph.sot import SE3, R3, SO3 +from dynamic_graph.sot.core import OpPointModifier from dynamic_graph.sot.core.derivator import Derivator_of_Vector from dynamic_graph.sot.core.feature_position import FeaturePosition from dynamic_graph.sot.core import RobotSimu, FeaturePoint6dRelative, \ @@ -57,6 +58,19 @@ class AbstractHumanoidRobot (object): "Jleft-wrist" for respectively the position and the jacobian. """ + AdditionalFrames = [] + """ + Additional frames are frames which are defined w.r.t an operational point + and provides an interesting transformation. + + It can be used, for instance, to store the sensor location. + + The contained elements must be triplets matching: + - additional frame name, + - transformation w.r.t to the operational point, + - operational point file. + """ + name = None """Entity name (internal use)""" @@ -102,6 +116,11 @@ class AbstractHumanoidRobot (object): corresponding to operational points. """ + frames = dict() + """ + Additional frames defined by using OpPointModifier. + """ + #FIXME: the following options are /not/ independent. # zmp requires acceleration which requires velocity. """ @@ -147,10 +166,10 @@ class AbstractHumanoidRobot (object): Additional information are located in two different XML files. """ model = dynamicType(name) + self.setProperties(model) model.setFiles(modelDir, modelName, specificitiesPath, jointRankPath) model.parse() - self.setProperties(model) return model def setProperties(self, model): @@ -259,6 +278,22 @@ class AbstractHumanoidRobot (object): memberName += i.capitalize() setattr(self, memberName, self.features[op]) + # --- additional frames --- + self.frame = dict() + for (frameName, transformation, signalName) in self.AdditionalFrames: + self.frame[frameName] = OpPointModifier( + "{0}_{1}".format(self.name, frameName)) + self.frame[frameName].setTransformation(transformation) + plug(self.dynamic.signal(signalName), + self.frame[frameName].positionIN) + plug(self.dynamic.signal("J{0}".format(signalName)), + self.frame[frameName].jacobianIN) + + self.frame[frameName].position.recompute( + self.frame[frameName].position.time + 1) + self.frame[frameName].jacobian.recompute( + self.frame[frameName].jacobian.time + 1) + def __init__(self, name): self.name = name -- GitLab