// Prepares an animation step. Records the positions, rotations, velocities
    // of the rigid bodies forming an animation into the animation step structure.
    void UpdateAnimationStep(float timeStep)
    {
        // HACK deal with two of first frame
        if (NormalizedTime == 0f && AnimationSteps.FirstOrDefault(x => x.NormalizedTime == 0f) != null)
        {
            return;
        }

        // var c = _master.Muscles.Count;
        var c        = BodyParts.Count;
        var animStep = new AnimationStep();

        animStep.TimeStep               = timeStep;
        animStep.NormalizedTime         = NormalizedTime;
        animStep.Velocities             = Enumerable.Repeat(Vector3.zero, c).ToList();
        animStep.VelocitiesLocal        = Enumerable.Repeat(Vector3.zero, c).ToList();
        animStep.AngularVelocities      = Enumerable.Repeat(Vector3.zero, c).ToList();
        animStep.AngularVelocitiesLocal = Enumerable.Repeat(Vector3.zero, c).ToList();
        animStep.Positions              = Enumerable.Repeat(Vector3.zero, c).ToList();
        animStep.Rotations              = Enumerable.Repeat(Quaternion.identity, c).ToList();
        animStep.CenterOfMass           = JointHelper002.GetCenterOfMassRelativeToRoot(BodyParts);
        //animStep.CenterOfMass = GetCenterOfMass();

        animStep.CenterOfMassVelocity = animStep.CenterOfMass - _lastCenterOfMass;
        animStep.Names           = BodyParts.Select(x => x.Name).ToList();
        animStep.SensorIsInTouch = new List <float>(SensorIsInTouch);
        _lastCenterOfMass        = animStep.CenterOfMass;

        var rootBone = BodyParts[0];

        foreach (var bodyPart in BodyParts)
        {
            var i = BodyParts.IndexOf(bodyPart);
            if (i == 0)
            {
                animStep.Rotations[i] = Quaternion.Inverse(bodyPart.InitialRootRotation) * bodyPart.Transform.rotation;
                animStep.Positions[i] = bodyPart.Transform.position - bodyPart.InitialRootPosition;
            }
            else
            {
                animStep.Rotations[i] = Quaternion.Inverse(rootBone.Transform.rotation) * bodyPart.Transform.rotation;
                animStep.Positions[i] = bodyPart.Transform.position - rootBone.Transform.position;
            }

            if (NormalizedTime != 0f)
            {
                animStep.Velocities[i]             = (bodyPart.Transform.position - _lastPosition[i]) / (_decisionRequester.DecisionPeriod * Time.fixedDeltaTime);;
                animStep.AngularVelocities[i]      = JointHelper002.CalcDeltaRotationNormalizedEuler(_lastRotation[i], bodyPart.Transform.rotation) / (_decisionRequester.DecisionPeriod * Time.fixedDeltaTime);;
                animStep.VelocitiesLocal[i]        = (animStep.Positions[i] - _lastPositionLocal[i]) / (_decisionRequester.DecisionPeriod * Time.fixedDeltaTime);;
                animStep.AngularVelocitiesLocal[i] = JointHelper002.CalcDeltaRotationNormalizedEuler(_lastRotationLocal[i], animStep.Rotations[i]) / (_decisionRequester.DecisionPeriod * Time.fixedDeltaTime);
            }

            if (bodyPart.Rigidbody != null)
            {
                bodyPart.Rigidbody.angularVelocity    = JointHelper002.CalcDeltaRotationNormalizedEuler(bodyPart.Transform.rotation, _lastRotation[i]) / (_decisionRequester.DecisionPeriod * Time.fixedDeltaTime);
                bodyPart.Rigidbody.velocity           = (bodyPart.Transform.position - _lastPosition[i]) / (_decisionRequester.DecisionPeriod * Time.fixedDeltaTime);
                bodyPart.Rigidbody.transform.position = bodyPart.Transform.position;
                bodyPart.Rigidbody.transform.rotation = bodyPart.Transform.rotation;
            }

            _lastPosition[i] = bodyPart.Transform.position;
            _lastRotation[i] = bodyPart.Transform.rotation;

            _lastPositionLocal[i] = animStep.Positions[i];
            _lastRotationLocal[i] = animStep.Rotations[i];
        }
        animStep.TransformPosition = transform.position;
        animStep.TransformRotation = transform.rotation;
        animStep.AngularMoment     = JointHelper002.GetAngularMoment(BodyParts);
        AnimationSteps.Add(animStep);
    }
Ejemplo n.º 2
0
    // Update values like ObsLocalPosition, ObsRotation, ... that will be accessed
    // by the agent as observations for the neural network. Also calculates distances
    // to an animation being mimicked
    public void UpdateObservations()
    {
        Quaternion rotation;
        Vector3    position;

        if (this == Root)
        {
            rotation = Quaternion.Inverse(InitialRootRotation) * Transform.rotation;
            position = Transform.position - InitialRootPosition;
        }
        else
        {
            rotation = Quaternion.Inverse(Root.Transform.rotation) * Transform.rotation;
            position = Transform.position - Root.Transform.position;
        }

        if (_firstRunComplete == false)
        {
            _lastUpdateObsTime = Time.time;
            _lastLocalPosition = position;
            _lastWorldPosition = Transform.position;
            _lastObsRotation   = rotation;
            _lastWorldRotation = Transform.rotation;
        }

        var dt = Time.fixedDeltaTime * _decisionRequester.DecisionPeriod;

        var velocity             = (position - _lastLocalPosition) / dt;
        var velocityWorld        = (Transform.position - _lastWorldPosition) / dt;
        var angularVelocity      = JointHelper002.CalcDeltaRotationNormalizedEuler(_lastObsRotation, rotation) / dt;
        var angularVelocityWorld = JointHelper002.CalcDeltaRotationNormalizedEuler(_lastWorldRotation, Transform.rotation) / dt;

        // old calulation for observation vector
        //angularVelocity = NormalizedEulerAngles(rotationVelocity.eulerAngles);
        //angularVelocity /= 128f;
        // old calculation end

        _lastUpdateObsTime = Time.time;
        _lastLocalPosition = position;
        _lastWorldPosition = Transform.position;
        _lastObsRotation   = rotation;
        _lastWorldRotation = Transform.rotation;

        //if (Name == "right_right_foot") {
        //    Debug.Log("^^^^^^^^^^^^");
        //    Debug.Log("body part name: " + Name);
        //    Debug.Log("animation angular velocity:" + _animationAngularVelocity);
        //    Debug.Log("angular velocity:" + angularVelocity);
        //    Debug.Log("animation angular velocity world:" + _animationAngularVelocityWorld);
        //    Debug.Log("angular velocity world:" + angularVelocityWorld);
        //    Debug.Log("rotation local:" + rotation.eulerAngles);
        //    Debug.Log("animation rotation local: " + _animationRotation.eulerAngles);
        //    Debug.Log("velocity world: " + velocityWorld);
        //    Debug.Log("animation velocity world:" + _animationVelocityWorld);
        //    Debug.Log("transform position:" + Transform.position);
        //    Debug.Log("animation position world: " + _animationPositionWorld);
        //    Debug.Log("dt:" + dt);
        //}

        ObsLocalPosition    = position;
        ObsRotation         = rotation;
        ObsRotationVelocity = angularVelocity;
        ObsVelocity         = velocity;

        ObsDeltaFromAnimationPosition = _animationPositionWorld - Transform.position;

        ObsAngleDeltaFromAnimationRotation = Quaternion.Angle(_animationRotation, rotation);
        ObsAngleDeltaFromAnimationRotation = JointHelper002.NormalizedAngle(ObsAngleDeltaFromAnimationRotation);

        ObsDeltaFromAnimationVelocity             = _animationVelocityWorld - velocityWorld;
        ObsDeltaFromAnimationAngularVelocity      = (_animationAngularVelocity - angularVelocity);
        ObsDeltaFromAnimationAngularVelocityWorld = (_animationAngularVelocityWorld - angularVelocityWorld);

        DebugMaxRotationVelocity = Vector3Max(DebugMaxRotationVelocity, angularVelocity);
        DebugMaxVelocity         = Vector3Max(DebugMaxVelocity, velocity);

        _firstRunComplete = true;
    }