예제 #1
0
 def testTransformInverse(self, nrOfTests=5):
     print("Running test testTransformInverse")
     for i in range(0, nrOfTests):
         #RTF.testReport("Running test testTransformInverse for position");
         p = self.randomPosition()
         T = self.randomTransform()
         pZero = iDynTree.Position()
         pZero.zero()
         self.checkPointEqual(p - p, pZero, "testTransformInverse failed")
         self.checkPointEqual(T.inverse() * T * p, p,
                              "testTransformInverse failed")
         #RTF.testReport("Running test testTransformInverse for Twist");
         v = self.randomTwist()
         vZero = iDynTree.Twist()
         vZero.zero()
         self.checkSpatialVectorEqual(v - v, vZero, "v-v is not zero")
         self.checkSpatialVectorEqual(T.inverse() * T * v, v,
                                      "T.inverse()*T*v is not v")
         #RTF.testReport("Running test testTransformInverse for Wrench");
         f = self.randomWrench()
         fZero = iDynTree.Wrench()
         fZero.zero()
         self.checkSpatialVectorEqual(f - f, fZero, "f-f is not zero")
         self.checkSpatialVectorEqual(T.inverse() * T * f, f,
                                      "T.inverse()*T*f is not f")
예제 #2
0
    def testDynComp(self):
        dynComp = iDynTree.DynamicsComputations()

        ok = dynComp.loadRobotModelFromFile('./model.urdf')

        #dynComp.getFloatingBase()

        # set state
        dofs = dynComp.getNrOfDegreesOfFreedom()
        print "dofs: {}".format(dofs)
        q = iDynTree.VectorDynSize.fromPyList(
            [random.random() for i in range(0, dofs)])
        dq = iDynTree.VectorDynSize.fromPyList(
            [random.random() for i in range(0, dofs)])
        ddq = iDynTree.VectorDynSize.fromPyList(
            [random.random() for i in range(0, dofs)])

        # set gravity
        grav = iDynTree.SpatialAcc.fromPyList([0.0, 0.0, -9.81, 0.0, 0.0, 0.0])
        dynComp.setRobotState(q, dq, ddq, grav)

        torques = iDynTree.VectorDynSize(dofs + 6)
        baseReactionForce = iDynTree.Wrench()

        # compute id with inverse dynamics
        dynComp.inverseDynamics(torques, baseReactionForce)

        # compute id with regressors
        nrOfParams = 10 * dynComp.getNrOfLinks()
        regr = iDynTree.MatrixDynSize(6 + dofs, nrOfParams)
        params = iDynTree.VectorDynSize(nrOfParams)
        dynComp.getDynamicsRegressor(regr)
        dynComp.getModelDynamicsParameters(params)

        np_reg = regr.toNumPy()
        np_params = params.toNumPy()
        generalizedForces = np.dot(np_reg, np_params)

        print 'Result of inverse dynamics:'
        #print 'baseReactionForce: {} \nTorques: {}'.format(baseReactionForce,torques)
        #print 'Generalized Forces: {}'.format(generalizedForces)

        # check consistency
        self.assertTrue(
            np.allclose(np.hstack(
                (baseReactionForce.toNumPy(), torques.toNumPy())),
                        generalizedForces,
                        rtol=1e-04,
                        atol=1e-04))
        print 'Test of DynamicsComputations completed successfully.'
예제 #3
0
    def simulateDynamicsIDynTree(self, samples, sample_idx, dynComp=None, xStdModel=None):
        # type: (Dict[str, np._ArrayLike], int, iDynTree.DynamicsComputations, np._ArrayLike[float]) -> np._ArrayLike[float]
        """ compute torques for one time step of measurements """

        if not dynComp:
            dynComp = self.dynComp
        if xStdModel is None:
            xStdModel = self.xStdModel
        world_gravity = iDynTree.SpatialAcc.fromList(self.gravity)

        # read sample data
        pos = samples['positions'][sample_idx]
        vel = samples['velocities'][sample_idx]
        acc = samples['accelerations'][sample_idx]

        # system state for iDynTree
        q = iDynTree.VectorDynSize.fromList(pos)
        dq = iDynTree.VectorDynSize.fromList(vel)
        ddq = iDynTree.VectorDynSize.fromList(acc)

        # calc torques and forces with iDynTree dynamicsComputation class
        if self.opt['floatingBase']:
            base_vel = samples['base_velocity'][sample_idx]
            base_acc = samples['base_acceleration'][sample_idx]
            rpy = samples['base_rpy'][sample_idx]

            # get the homogeneous transformation that transforms vectors expressed
            # in the base reference frame to frames expressed in the world
            # reference frame, i.e. pos_world = world_T_base*pos_base
            # for identification purposes, the position does not matter but rotation is taken
            # from IMU estimation. The gravity, base velocity and acceleration all need to be
            # expressed in world frame
            rot = iDynTree.Rotation.RPY(rpy[0], rpy[1], rpy[2])
            pos = iDynTree.Position.Zero()
            world_T_base = iDynTree.Transform(rot, pos).inverse()

            '''
            # rotate base vel and acc to world frame
            to_world = world_T_base.getRotation().toNumPy()
            base_vel[0:3] = to_world.dot(base_vel[0:3])
            base_vel[3:] = to_world.dot(base_vel[3:])
            base_acc[0:3] = to_world.dot(base_acc[0:3])
            base_acc[3:] = to_world.dot(base_acc[3:])
            '''

            # The twist (linear, angular velocity) of the base, expressed in the world
            # orientation frame and with respect to the base origin
            base_velocity = iDynTree.Twist.fromList(base_vel)
            # The 6d classical acceleration (linear, angular acceleration) of the base
            # expressed in the world orientation frame and with respect to the base origin
            base_acceleration = iDynTree.ClassicalAcc.fromList(base_acc)

            dynComp.setRobotState(q, dq, ddq, world_T_base, base_velocity, base_acceleration,
                                  world_gravity)
        else:
            dynComp.setRobotState(q, dq, ddq, world_gravity)

        # compute inverse dynamics
        torques = iDynTree.VectorDynSize(self.num_dofs)
        baseReactionForce = iDynTree.Wrench()
        dynComp.inverseDynamics(torques, baseReactionForce)
        torques = torques.toNumPy()

        if self.opt['identifyFriction']:
            # add friction torques
            # constant
            sign = 1 #np.sign(vel)
            p_constant = range(self.friction_params_start, self.friction_params_start+self.num_dofs)
            torques += sign*xStdModel[p_constant]

            # vel dependents
            if not self.opt['identifyGravityParamsOnly']:
                # (take only first half of params as they are not direction dependent in urdf anyway)
                p_vel = range(self.friction_params_start+self.num_dofs, self.friction_params_start+self.num_dofs*2)
                torques += xStdModel[p_vel]*vel

        if self.opt['floatingBase']:
            return np.concatenate((baseReactionForce.toNumPy(), torques))
        else:
            return torques
예제 #4
0
def test_regressors():
    #get some random state values and compare inverse dynamics torques with torques
    #obtained with regressor and parameter vector

    idyn_model = iDynTree.Model()
    iDynTree.modelFromURDF(urdf_file, idyn_model)

    # create generator instance and load model
    generator = iDynTree.DynamicsRegressorGenerator()
    generator.loadRobotAndSensorsModelFromFile(urdf_file)
    regrXml = '''
    <regressor>
      <baseLinkDynamics/>
      <jointTorqueDynamics>
        <allJoints/>
      </jointTorqueDynamics>
    </regressor>'''
    generator.loadRegressorStructureFromString(regrXml)
    num_model_params = generator.getNrOfParameters()
    num_out = generator.getNrOfOutputs()
    n_dofs = generator.getNrOfDegreesOfFreedom()
    num_samples = 100

    xStdModel = iDynTree.VectorDynSize(num_model_params)
    generator.getModelParameters(xStdModel)
    xStdModel = xStdModel.toNumPy()

    gravity_twist = iDynTree.Twist.fromList([0, 0, -9.81, 0, 0, 0])
    gravity_acc = iDynTree.SpatialAcc.fromList([0, 0, -9.81, 0, 0, 0])

    dynComp = iDynTree.DynamicsComputations()
    dynComp.loadRobotModelFromFile(urdf_file)

    regressor_stack = np.zeros(shape=((n_dofs + 6) * num_samples,
                                      num_model_params))
    idyn_torques = np.zeros(shape=((n_dofs + 6) * num_samples))
    contactForceSum = np.zeros(shape=((n_dofs + 6) * num_samples))

    for sample_index in range(0, num_samples):
        q = iDynTree.VectorDynSize.fromList(
            ((np.random.ranf(n_dofs) * 2 - 1) * np.pi).tolist())
        dq = iDynTree.VectorDynSize.fromList(
            ((np.random.ranf(n_dofs) * 2 - 1) * np.pi).tolist())
        ddq = iDynTree.VectorDynSize.fromList(
            ((np.random.ranf(n_dofs) * 2 - 1) * np.pi).tolist())
        base_vel = np.pi * np.random.rand(6)
        base_acc = np.pi * np.random.rand(6)

        #rpy = [0,0,0]
        rpy = np.random.ranf(3) * 0.1
        rot = iDynTree.Rotation.RPY(rpy[0], rpy[1], rpy[2])
        pos = iDynTree.Position.Zero()
        world_T_base = iDynTree.Transform(rot, pos).inverse()

        # rotate base vel and acc to world frame
        to_world = world_T_base.getRotation().toNumPy()
        base_vel[0:3] = to_world.dot(base_vel[0:3])
        base_vel[3:] = to_world.dot(base_vel[3:])
        base_acc[0:3] = to_world.dot(base_acc[0:3])
        base_acc[3:] = to_world.dot(base_acc[3:])

        base_velocity = iDynTree.Twist.fromList(base_vel)
        base_acceleration = iDynTree.Twist.fromList(base_acc)
        base_acceleration_acc = iDynTree.ClassicalAcc.fromList(base_acc)

        # regressor
        generator.setRobotState(q, dq, ddq, world_T_base, base_velocity,
                                base_acceleration, gravity_twist)

        regressor = iDynTree.MatrixDynSize(num_out, num_model_params)
        knownTerms = iDynTree.VectorDynSize(num_out)
        if not generator.computeRegressor(regressor, knownTerms):
            print("Error during numeric computation of regressor")

        #the base forces are expressed in the base frame for the regressor, so transform them
        to_world = np.fromstring(world_T_base.getRotation().toString(),
                                 sep=' ').reshape((3, 3))
        regressor = regressor.toNumPy()
        regressor[0:3, :] = to_world.dot(regressor[0:3, :])
        regressor[3:6, :] = to_world.dot(regressor[3:6, :])

        row_index = (
            n_dofs + 6
        ) * sample_index  # index for current row in stacked regressor matrix
        np.copyto(regressor_stack[row_index:row_index + n_dofs + 6], regressor)

        # inverse dynamics
        #dynComp.setFloatingBase('base_link')
        dynComp.setRobotState(q, dq, ddq, world_T_base, base_velocity,
                              base_acceleration_acc, gravity_acc)
        torques = iDynTree.VectorDynSize(n_dofs)
        baseReactionForce = iDynTree.Wrench()
        dynComp.inverseDynamics(torques, baseReactionForce)

        torques = np.concatenate(
            (baseReactionForce.toNumPy(), torques.toNumPy()))
        np.copyto(idyn_torques[row_index:row_index + n_dofs + 6], torques)

        # contacts
        dim = n_dofs + 6
        contact = np.array([0, 0, 10, 0, 0, 0])
        jacobian = iDynTree.MatrixDynSize(6, dim)
        dynComp.getFrameJacobian(contactFrame, jacobian)
        jacobian = jacobian.toNumPy()
        contactForceSum[sample_index * dim:(sample_index + 1) *
                        dim] = jacobian.T.dot(contact)

    regressor_torques = np.dot(regressor_stack, xStdModel) + contactForceSum
    idyn_torques += contactForceSum

    error = np.reshape(regressor_torques - idyn_torques, (num_samples, dim))

    #plots = plt.plot(range(0, num_samples), error)
    #plt.legend(plots, ['f_x', 'f_y', 'f_z', 'm_x', 'm_y', 'm_z', 'j_0'])
    #plt.show()

    error_norm = la.norm(error)
    print(error_norm)
    assert error_norm <= 0.01
예제 #5
0
# Note that we are using the "fixed base" version of setRobotState
regrGen.setRobotState(qj, dqj, ddqj, gravity)

# TODO: set sensor values

# Now we can compute the regressor
regressor = iDynTree.MatrixDynSize(outs, params)
knownTerms = iDynTree.VectorDynSize(outs)
cadParams = iDynTree.VectorDynSize(params)

# We can get the current model parameters (probably extracted from CAD)
regrGen.getModelParameters(cadParams)

# We want to set the measure for the `l_arm_ft_sensor`
sensorMeasure = iDynTree.Wrench()
sensorMeasure.setVal(0, 0.0)
sensorMeasure.setVal(1, 0.0)
sensorMeasure.setVal(2, 10.0)
sensorMeasure.setVal(3, 0.4)
sensorMeasure.setVal(4, 0.6)
sensorMeasure.setVal(5, 0.5)

sensorIndex = \
    regrGen.getSensorsModel().getSensorIndex(iDynTree.SIX_AXIS_FORCE_TORQUE,'r_arm_ft_sensor')
regrGen.getSensorsMeasurements().setMeasurement(iDynTree.SIX_AXIS_FORCE_TORQUE,
                                                sensorIndex, sensorMeasure)

regrGen.computeRegressor(regressor, knownTerms)

# Convert data to numpy
예제 #6
0
 def randomWrench(self):
     ''' Return a random wrench '''
     res = iDynTree.Wrench()
     for i in range(0, 6):
         res.setVal(i, random.uniform(-10, 10))
     return res
예제 #7
0
    q.zero()
    dq = iDynTree.VectorDynSize(n_dofs)
    #dq.fromList([1.0]*n_dofs)
    dq.zero()
    ddq = iDynTree.VectorDynSize(n_dofs)
    ddq.zero()
    world_gravity = iDynTree.SpatialAcc.fromList([0, 0, -9.81, 0, 0, 0])
    base_velocity = iDynTree.Twist()
    base_velocity.zero()
    base_acceleration = iDynTree.ClassicalAcc()
    base_acceleration.zero()
    rot = iDynTree.Rotation.RPY(0, 0, 0)
    pos = iDynTree.Position.Zero()
    world_T_base = iDynTree.Transform(rot, pos)
    torques = iDynTree.VectorDynSize(n_dofs)
    baseReactionForce = iDynTree.Wrench()

    m = iDynTree.MatrixDynSize(n_dofs, n_dofs)
    maxima = [0]*n_dofs
    minima = [99999]*n_dofs
    getMaxima = 1

    for i in range(n_dofs):
        for pos in np.arange(limits[jointNames[i]]['lower'], limits[jointNames[i]]['upper'], 0.01):
            q.zero()

            q[i] = pos
            if getMaxima:
                # saggital = pitch, transversal = yaw, lateral = roll
                if i == jointNames.index('LHipYaw'):
                    # lift right leg up 90 deg