Example #1
0
    def _readJoint(self):
        # use jointStack[-1] to peek at the top of the jointStack
        currentJoint = self.jointStack[-1]
        name = self._token()
        # name will be 'Site' for End Site joints.
        if name == 'Site':
            name = currentJoint.parent.name + "_end"
        currentJoint.name = name

        self._checkToken("{")
        while True:
            token = self._token()
            if token == "OFFSET":
                x = self._floatToken()
                y = self._floatToken()
                z = self._floatToken()
                currentJoint.positionOffset = \
                        convertCGtoNED(np.array([[x,y,z]]).T*self.conversionFactor)
            elif token == "CHANNELS":
                n = self._intToken()
                channels = []
                for i in range(n):
                    token = self._token()
                    if token not in ["Xposition","Yposition","Zposition",\
                                     "Xrotation","Yrotation","Zrotation"]:
                        raise SyntaxError, "Syntax error in line %d: Invalid \
channel name '%s'" % (self.line, token)
                    else:
                        channels.append(token)
                self.totalChannels += n
                currentJoint.channels = channels
            elif token in ("JOINT", "End"):
                if token == "JOINT":
                    joint = SampledJoint(currentJoint)
                else:
                    joint = PointTrajectory(currentJoint)
                joint.channels = []
                self.jointStack.append(joint)
                self._readJoint()
            elif token == "}":
                self.jointStack.pop()
                break
            else:
                raise SyntaxError,\
                    "Syntax error in line %d: Unknown keyword '%s'" %(
                            self.line,token)
Example #2
0
def testAgainstReality():
    dir = path.dirname(__file__)
    filebase = path.join(dir, "swing")
    refbase = path.join(dir, "stand")
    magbases = [path.join(dir, f) for f in ['magsweep1', 'magsweep2']]
    maglookup = {'Upper Leg IMU': '66', 'Orient 8': '8', 'Orient 43': '43'}
    magSamples = 2000
    refTime = 1.0
    posStdDev = 0.0005
    rotStdDev = 0.004
    ref3D = SplinedMarkerCapture(loadQualisysTSVFile(refbase + "_3D.tsv"),
                                 positionStdDev=posStdDev)
    ref6D = SplinedMarkerCapture(loadQualisysTSVFile(refbase + "_6D.tsv"),
                                 rotationStdDev=rotStdDev)
    capture3D = SplinedMarkerCapture(loadQualisysTSVFile(filebase + "_3D.tsv"),
                                     positionStdDev=posStdDev)
    captureSD = SensorDataCapture.load(filebase + ".sdc")
    hip, thigh, knee, shin, ankle = \
            ['Hip', 'Thigh', 'Knee Hinge', 'Shin', 'Ankle']
    jointNames = ['Upper Leg', 'Lower Leg', 'Foot']
    jointAbbrevs = ['femur', 'tibia', 'foot']
    orientIDs = ['66', '43', '8']
    jointMarkerNames = [hip, knee, ankle]
    refMarkerNames = [[thigh, knee], [shin, ankle], []]
    imuMarkerNames = \
            [[j + ' IMU - ' + str(i) for i in range(1,4)] for j in jointNames]
    jointMarkerSets = lambda c: [
        list(map(c.marker, jointMarkerNames)),
        [list(map(c.marker, r)) for r in refMarkerNames],
        [list(map(c.marker, i)) for i in imuMarkerNames]
    ]
    imuMarkerSets = lambda c: [[
        c.marker(i[0]) for i in imuMarkerNames
    ], [list(map(c.marker, i[1:])) for i in imuMarkerNames]]
    jointRefTrajectories = [
        MultiMarkerTrajectory(j, r + i, refTime=refTime)
        for j, r, i in zip(*(jointMarkerSets(ref3D)))
    ]
    jointTrajectories = [
        MultiMarkerTrajectory(j, r + i, refVectors=m.refVectors) \
            for j, r, i, m in \
                zip(*(jointMarkerSets(capture3D) + [jointRefTrajectories]))]
    imuRefTrajectories = [
        MultiMarkerTrajectory(p, r, refTime=refTime)
        for p, r in zip(*(imuMarkerSets(ref3D)))
    ]
    imuVecTrajectories = [
        MultiMarkerTrajectory(p, r, refVectors=m.refVectors)
        for p, r, m in zip(*(imuMarkerSets(capture3D) + [imuRefTrajectories]))
    ]
    imuRefMarkers = [ref6D.marker(j + ' IMU') for j in jointNames]
    imuOffsets = [
        i.position(refTime) - j.position(refTime)
        for i, j in zip(imuRefTrajectories, jointRefTrajectories)
    ]
    imuRotations = [
        t.rotation(refTime).conjugate * m.rotation(refTime)
        for t, m in zip(imuRefTrajectories, imuRefMarkers)
    ]
    imuTrajectories = [
        OffsetTrajectory(v, o, r)
        for v, o, r in zip(imuVecTrajectories, imuOffsets, imuRotations)
    ]
    imuData = [captureSD.device(i) for i in orientIDs]
    joints = []
    for i in range(len(jointNames)):
        name = jointNames[i]
        traj = jointTrajectories[i]
        if i == 0:
            model = SampledBodyModel(name)
            model.positionKeyFrames = traj.posMarker.positionKeyFrames
            joint = model
        else:
            parent = joints[-1]
            refTraj = jointRefTrajectories[i]
            parentRefTraj = jointRefTrajectories[i - 1]
            pos = refTraj.position(refTime)
            parentPos = parentRefTraj.position(refTime)
            joint = SampledJoint(joints[-1], name, offset=(pos - parentPos))
        joint.rotationKeyFrames = traj.rotationKeyFrames
        joints.append(joint)
    model = SplinedBodyModel(model)
    joints = model.joints
    imuJointTrajectories = [
        OffsetTrajectory(j, o, r)
        for j, o, r in zip(joints, imuOffsets, imuRotations)
    ]
    positionSets = []
    valueSets = []
    for magbase in magbases:
        orient = SensorDataCapture.load(magbase + '.sdc')
        optical = loadQualisysTSVFile(magbase + '_6D.tsv')
        for marker in optical.markers:
            device = orient.device(maglookup[marker.id])
            magData = device.sensorData('magnetometer').values
            positionSets.append(marker.positionKeyFrames.values)
            valueSets.append(
                marker.rotationKeyFrames.values.rotateVector(magData))
    positions = np.hstack(positionSets)
    values = np.hstack(valueSets)
    valid = ~np.any(np.isnan(positions), axis=0) & ~np.any(np.isnan(values),
                                                           axis=0)
    dev = values - np.median(values[:, valid], axis=1).reshape((3, 1))
    step = np.shape(values[:, valid])[1] // magSamples
    posSamples = positions[:, valid][:, ::step]
    valSamples = values[:, valid][:, ::step]
    environment = Environment()
    environment.magneticField = \
            NaturalNeighbourInterpolatedField(posSamples, valSamples)
    sim = Simulation(environment=environment)
    sim.time = model.startTime
    distortIMUs = []
    dt = 1 / capture3D.sampled.frameRate
    for traj in imuJointTrajectories:
        platform = IdealIMU(sim, traj)
        distortIMUs.append(BasicIMUBehaviour(platform, dt))
    sim.run(model.endTime)
    for imu in range(3):
        for sensorName in ['accelerometer', 'magnetometer', 'gyroscope']:
            sim = getattr(distortIMUs[imu].imu, sensorName).rawMeasurements
            true = imuData[imu].sensorData(sensorName)(sim.timestamps +
                                                       model.startTime)
            yield assert_vectors_correlated, sim.values, true, 0.8
Example #3
0
def loadASFFile(asfFileName, amcFileName, scaleFactor, framePeriod):
    """
    Load motion capture data from an ASF and AMC file pair.

    @param asfFileName: Name of the ASF file containing the description of
        the rigid body model
    @param amcFileName: Name of the AMC file containing the motion data
    @param scaleFactor: Scaling factor to convert lengths to m. For data
        from the CMU motion capture corpus this should be 2.54/100 to
        convert from inches to metres.

    @return: A {SampledBodyModel} representing the root of the rigid body
        model structure.
    """
    with open(asfFileName, 'r') as asfFile:
        data = asfParser.parseFile(asfFile)
        scale = (1.0 / data.units.get('length', 1)) * scaleFactor

        bones = dict((bone.name, bone) for bone in data.bones)
        asfModel = ASFRoot(data.root)

        for entry in data.hierarchy:
            parent = asfModel.getBone(entry.parent)
            for childName in entry.children:
                ASFBone(parent, bones[childName], scale)

        imusimModel = SampledBodyModel('root')
        for subtree in asfModel.children:
            for bone in subtree:
                if not bone.isDummy:
                    offset = vector(0, 0, 0)
                    ancestors = bone.ascendTree()
                    while True:
                        ancestor = ancestors.next().parent
                        offset += ancestor.childoffset
                        if not ancestor.isDummy:
                            break

                    SampledJoint(parent=imusimModel.getJoint(ancestor.name),
                                 name=bone.name,
                                 offset=offset)
                if not bone.hasChildren:
                    PointTrajectory(parent=imusimModel.getJoint(bone.name),
                                    name=bone.name + '_end',
                                    offset=bone.childoffset)

        with open(amcFileName) as amcFile:
            motion = amcParser.parseFile(amcFile)
            t = 0
            for frame in motion.frames:
                for bone in frame.bones:
                    bonedata = asfModel.getBone(bone.name)
                    if bone.name == 'root':
                        data = dict((chan.lower(), v) for chan, v in zip(
                            bonedata.channels, bone.channels))
                        position = convertCGtoNED(
                            scale * vector(data['tx'], data['ty'], data['tz']))
                        imusimModel.positionKeyFrames.add(t, position)

                    axes, angles = zip(*[(chan[-1], angle)
                                         for chan, angle in zip(
                                             bonedata.channels, bone.channels)
                                         if chan.lower().startswith('r')])
                    rotation = (bonedata.rotationOffset.conjugate *
                                Quaternion.fromEuler(angles[::-1], axes[::-1]))
                    joint = imusimModel.getJoint(bone.name)
                    if joint.hasParent:
                        parentRot = joint.parent.rotationKeyFrames.latestValue
                        parentRotOffset = bonedata.parent.rotationOffset
                        rotation = parentRot * parentRotOffset * rotation
                    else:
                        rotation = convertCGtoNED(rotation)
                    joint.rotationKeyFrames.add(t, rotation)
                t += framePeriod

        return imusimModel
Example #4
0
def testAgainstReality():
    dir = path.dirname(__file__)
    filebase = path.join(dir, "swing")
    refbase = path.join(dir, "stand")
    magbases = [path.join(dir, f) for f in ['magsweep1', 'magsweep2']]
    maglookup = {
        'Upper Leg IMU' : '66',
        'Orient 8' : '8',
        'Orient 43': '43'}
    magSamples = 2000
    refTime = 1.0
    posStdDev = 0.0005
    rotStdDev = 0.004
    ref3D = SplinedMarkerCapture(
        loadQualisysTSVFile(refbase + "_3D.tsv"), positionStdDev=posStdDev)
    ref6D = SplinedMarkerCapture(
        loadQualisysTSVFile(refbase + "_6D.tsv"), rotationStdDev=rotStdDev)
    capture3D = SplinedMarkerCapture(
        loadQualisysTSVFile(filebase + "_3D.tsv"), positionStdDev=posStdDev)
    captureSD = SensorDataCapture.load(filebase + ".sdc")
    hip, thigh, knee, shin, ankle = \
            ['Hip', 'Thigh', 'Knee Hinge', 'Shin', 'Ankle']
    jointNames = ['Upper Leg', 'Lower Leg', 'Foot']
    jointAbbrevs = ['femur', 'tibia', 'foot']
    orientIDs = ['66', '43', '8']
    jointMarkerNames = [hip, knee, ankle]
    refMarkerNames = [[thigh, knee], [shin, ankle], []]
    imuMarkerNames = \
            [[j + ' IMU - ' + str(i) for i in range(1,4)] for j in jointNames]
    jointMarkerSets = lambda c: [
        map(c.marker, jointMarkerNames),
        [map(c.marker, r) for r in refMarkerNames],
        [map(c.marker, i) for i in imuMarkerNames]]
    imuMarkerSets = lambda c: [
        [c.marker(i[0]) for i in imuMarkerNames],
        [map(c.marker,i[1:]) for i in imuMarkerNames]]
    jointRefTrajectories = [MultiMarkerTrajectory(j, r + i, refTime=refTime)
        for j, r, i in zip(*(jointMarkerSets(ref3D)))]
    jointTrajectories = [
        MultiMarkerTrajectory(j, r + i, refVectors=m.refVectors) \
            for j, r, i, m in \
                zip(*(jointMarkerSets(capture3D) + [jointRefTrajectories]))]
    imuRefTrajectories = [MultiMarkerTrajectory(p, r, refTime=refTime)
        for p, r in zip(*(imuMarkerSets(ref3D)))]
    imuVecTrajectories = [MultiMarkerTrajectory(p, r, refVectors=m.refVectors)
        for p, r, m in zip(*(imuMarkerSets(capture3D) + [imuRefTrajectories]))]
    imuRefMarkers = [ref6D.marker(j + ' IMU') for j in jointNames]
    imuOffsets = [i.position(refTime) - j.position(refTime)
        for i, j in zip(imuRefTrajectories, jointRefTrajectories)]
    imuRotations = [t.rotation(refTime).conjugate * m.rotation(refTime)
        for t, m in zip(imuRefTrajectories, imuRefMarkers)]
    imuTrajectories = [OffsetTrajectory(v, o, r)
        for v, o, r in zip(imuVecTrajectories, imuOffsets, imuRotations)]
    imuData = [captureSD.device(i) for i in orientIDs]
    joints = []
    for i in range(len(jointNames)):
        name = jointNames[i]
        traj = jointTrajectories[i]
        if i == 0:
            model = SampledBodyModel(name)
            model.positionKeyFrames = traj.posMarker.positionKeyFrames
            joint = model
        else:
            parent = joints[-1]
            refTraj = jointRefTrajectories[i]
            parentRefTraj = jointRefTrajectories[i - 1]
            pos = refTraj.position(refTime)
            parentPos = parentRefTraj.position(refTime)
            joint = SampledJoint(joints[-1],name, offset=(pos - parentPos))
        joint.rotationKeyFrames = traj.rotationKeyFrames
        joints.append(joint)
    model = SplinedBodyModel(model)
    joints = model.joints
    imuJointTrajectories = [OffsetTrajectory(j, o, r)
        for j, o, r in zip(joints, imuOffsets, imuRotations)]
    positionSets = []
    valueSets = []
    for magbase in magbases:
        orient = SensorDataCapture.load(magbase + '.sdc')
        optical = loadQualisysTSVFile(magbase + '_6D.tsv')
        for marker in optical.markers:
            device = orient.device(maglookup[marker.id])
            magData = device.sensorData('magnetometer').values
            positionSets.append(marker.positionKeyFrames.values)
            valueSets.append(
                    marker.rotationKeyFrames.values.rotateVector(magData))
    positions = np.hstack(positionSets)
    values = np.hstack(valueSets)
    valid = ~np.any(np.isnan(positions),axis=0) & ~np.any(np.isnan(values),axis=0)
    dev = values - np.median(values[:,valid],axis=1).reshape((3,1))
    step = np.shape(values[:,valid])[1] / magSamples
    posSamples = positions[:,valid][:,::step]
    valSamples = values[:,valid][:,::step]
    environment = Environment()
    environment.magneticField = \
            NaturalNeighbourInterpolatedField(posSamples, valSamples)
    sim = Simulation(environment=environment)
    sim.time = model.startTime
    distortIMUs = []
    dt = 1/capture3D.sampled.frameRate
    for traj in imuJointTrajectories:
        platform = IdealIMU(sim, traj)
        distortIMUs.append(BasicIMUBehaviour(platform, dt))
    sim.run(model.endTime)
    for imu in range(3):
        for sensorName in ['accelerometer', 'magnetometer', 'gyroscope']:
            sim = getattr(distortIMUs[imu].imu,sensorName).rawMeasurements
            true = imuData[imu].sensorData(sensorName)(sim.timestamps + model.startTime)
            yield assert_vectors_correlated, sim.values, true, 0.8