void updateArmPosition(GameObject myo, ArmTransform armSegment, Quaternion _antiYaw, float _referenceRoll) { ThalmicMyo thalmicMyo = myo.GetComponent<ThalmicMyo> (); bool updateReference = false; if (myo.Equals(myoLower)) { // Update references when the pose becomes fingers spread or the q key is pressed. if (thalmicMyo.pose != _lastPose) { _lastPose = thalmicMyo.pose; if (thalmicMyo.pose == Pose.Fist) { updateReference = true; ExtendUnlockAndNotifyUserAction (thalmicMyo); } } if (Input.GetKeyDown ("r")) { updateReference = true; } } // Update references. This anchors the joint on-screen such that it faces forward away // from the viewer when the Myo armband is oriented the way it is when these references are taken. if (updateReference) { _antiYawUpper = Quaternion.FromToRotation ( new Vector3 (myoUpper.transform.forward.x, myoUpper.transform.forward.y, myoUpper.transform.forward.z), new Vector3 (1, 0, 0) ); // _referenceRoll represents how many degrees the Myo armband is rotated clockwise // about its forward axis (when looking down the wearer's arm towards their hand) from the reference zero // roll direction. This direction is calculated and explained below. When this reference is // taken, the joint will be rotated about its forward axis such that it faces upwards when // the roll value matches the reference. Vector3 referenceZeroRoll = computeZeroRollVector (myoUpper.transform.forward, myoUpper); _referenceRollUpper = rollFromZero (referenceZeroRoll, myoUpper.transform.forward, myoUpper.transform.up); // _antiYaw represents a rotation of the Myo armband about the Y axis (up) which aligns the forward // vector of the rotation with Z = 1 when the wearer's arm is pointing in the reference direction. _antiYawLower = Quaternion.FromToRotation ( new Vector3 (myoLower.transform.forward.x, 0, myoLower.transform.forward.z), new Vector3 (1,0,0) ); _antiYaw = _antiYawLower; // _referenceRoll represents how many degrees the Myo armband is rotated clockwise // about its forward axis (when looking down the wearer's arm towards their hand) from the reference zero // roll direction. This direction is calculated and explained below. When this reference is // taken, the joint will be rotated about its forward axis such that it faces upwards when // the roll value matches the reference. referenceZeroRoll = computeZeroRollVector (myoLower.transform.forward, myoLower); _referenceRollLower = rollFromZero (referenceZeroRoll, myoLower.transform.forward, myoLower.transform.up); _referenceRoll = _referenceRollLower; } // Current zero roll vector and roll value. Vector3 zeroRoll = computeZeroRollVector (myo.transform.forward, myo); float roll = rollFromZero (zeroRoll, myo.transform.forward, myo.transform.up); // The relative roll is simply how much the current roll has changed relative to the reference roll. // adjustAngle simply keeps the resultant value within -180 to 180 degrees. float relativeRoll = normalizeAngle (roll - _referenceRoll); // antiRoll represents a rotation about the myo Armband's forward axis adjusting for reference roll. Quaternion antiRoll = Quaternion.AngleAxis (relativeRoll, myo.transform.forward); // Here the anti-roll and yaw rotations are applied to the myo Armband's forward direction to yield // the orientation of the joint. armSegment.transform.rotation = _antiYaw * antiRoll * Quaternion.LookRotation (myo.transform.forward); // The above calculations were done assuming the Myo armbands's +x direction, in its own coordinate system, // was facing toward the wearer's elbow. If the Myo armband is worn with its +x direction facing the other way, // the rotation needs to be updated to compensate. if (thalmicMyo.xDirection == Thalmic.Myo.XDirection.TowardWrist) { // Mirror the rotation around the XZ plane in Unity's coordinate system (XY plane in Myo's coordinate // system). This makes the rotation reflect the arm's orientation, rather than that of the Myo armband. armSegment.transform.rotation = new Quaternion(armSegment.transform.localRotation.x, -armSegment.transform.localRotation.y, armSegment.transform.localRotation.z, -armSegment.transform.localRotation.w); } }
void updateArmPosition(GameObject myo, ArmTransform armSegment, Quaternion _antiYaw, float _referenceRoll) { ThalmicMyo thalmicMyo = myo.GetComponent <ThalmicMyo> (); bool updateReference = false; if (myo.Equals(myoLower)) { // Update references when the pose becomes fingers spread or the q key is pressed. if (thalmicMyo.pose != _lastPose) { _lastPose = thalmicMyo.pose; if (thalmicMyo.pose == Pose.Fist) { updateReference = true; ExtendUnlockAndNotifyUserAction(thalmicMyo); } } if (Input.GetKeyDown("r")) { updateReference = true; } } // Update references. This anchors the joint on-screen such that it faces forward away // from the viewer when the Myo armband is oriented the way it is when these references are taken. if (updateReference) { _antiYawUpper = Quaternion.FromToRotation( new Vector3(myoUpper.transform.forward.x, myoUpper.transform.forward.y, myoUpper.transform.forward.z), new Vector3(1, 0, 0) ); // _referenceRoll represents how many degrees the Myo armband is rotated clockwise // about its forward axis (when looking down the wearer's arm towards their hand) from the reference zero // roll direction. This direction is calculated and explained below. When this reference is // taken, the joint will be rotated about its forward axis such that it faces upwards when // the roll value matches the reference. Vector3 referenceZeroRoll = computeZeroRollVector(myoUpper.transform.forward, myoUpper); _referenceRollUpper = rollFromZero(referenceZeroRoll, myoUpper.transform.forward, myoUpper.transform.up); // _antiYaw represents a rotation of the Myo armband about the Y axis (up) which aligns the forward // vector of the rotation with Z = 1 when the wearer's arm is pointing in the reference direction. _antiYawLower = Quaternion.FromToRotation( new Vector3(myoLower.transform.forward.x, 0, myoLower.transform.forward.z), new Vector3(1, 0, 0) ); _antiYaw = _antiYawLower; // _referenceRoll represents how many degrees the Myo armband is rotated clockwise // about its forward axis (when looking down the wearer's arm towards their hand) from the reference zero // roll direction. This direction is calculated and explained below. When this reference is // taken, the joint will be rotated about its forward axis such that it faces upwards when // the roll value matches the reference. referenceZeroRoll = computeZeroRollVector(myoLower.transform.forward, myoLower); _referenceRollLower = rollFromZero(referenceZeroRoll, myoLower.transform.forward, myoLower.transform.up); _referenceRoll = _referenceRollLower; } // Current zero roll vector and roll value. Vector3 zeroRoll = computeZeroRollVector(myo.transform.forward, myo); float roll = rollFromZero(zeroRoll, myo.transform.forward, myo.transform.up); // The relative roll is simply how much the current roll has changed relative to the reference roll. // adjustAngle simply keeps the resultant value within -180 to 180 degrees. float relativeRoll = normalizeAngle(roll - _referenceRoll); // antiRoll represents a rotation about the myo Armband's forward axis adjusting for reference roll. Quaternion antiRoll = Quaternion.AngleAxis(relativeRoll, myo.transform.forward); // Here the anti-roll and yaw rotations are applied to the myo Armband's forward direction to yield // the orientation of the joint. armSegment.transform.rotation = _antiYaw * antiRoll * Quaternion.LookRotation(myo.transform.forward); // The above calculations were done assuming the Myo armbands's +x direction, in its own coordinate system, // was facing toward the wearer's elbow. If the Myo armband is worn with its +x direction facing the other way, // the rotation needs to be updated to compensate. if (thalmicMyo.xDirection == Thalmic.Myo.XDirection.TowardWrist) { // Mirror the rotation around the XZ plane in Unity's coordinate system (XY plane in Myo's coordinate // system). This makes the rotation reflect the arm's orientation, rather than that of the Myo armband. armSegment.transform.rotation = new Quaternion(armSegment.transform.localRotation.x, -armSegment.transform.localRotation.y, armSegment.transform.localRotation.z, -armSegment.transform.localRotation.w); } }