コード例 #1
0
ファイル: AgentsPlayback.cs プロジェクト: lgsvl/simulator
                /// <summary>
                /// Constructor
                /// </summary>
                /// <param name="startTime">Playback time when this action starts</param>
                /// <param name="agent">Scenario agent that will be moved by this action</param>
                /// <param name="previousAction">Previous agent's move action used for initial parameters</param>
                /// <param name="destination">Agent's destination position applied when the action ends</param>
                /// <param name="rotation">Agent's rotation which will be applied when this action is performed</param>
                /// <param name="destinationSpeed">Agent's destination speed used during the playback movement</param>
                /// <param name="acceleration">Agent's acceleration used during the playback movement</param>
                public AgentMoveAction(float startTime, ScenarioAgent agent, AgentMoveAction previousAction,
                                       Vector3 destination, Quaternion rotation, float destinationSpeed, float acceleration) : base(
                        startTime)
                {
                    Agent            = agent;
                    InitialPosition  = previousAction?.Destination ?? Agent.TransformForPlayback.position;
                    InitialRotation  = Agent.TransformForPlayback.rotation;
                    Destination      = destination;
                    Rotation         = rotation;
                    InitialSpeed     = previousAction?.DestinationSpeed ?? 0.0f;
                    DestinationSpeed = destinationSpeed;
                    Acceleration     = acceleration;
                    var distance = Vector3.Distance(InitialPosition, destination);

                    if (acceleration > 0)
                    {
                        // If max speed is lower than the initial speed convert acceleration to deceleration
                        if (destinationSpeed < InitialSpeed)
                        {
                            Acceleration *= -1;
                        }

                        if (!UniformlyAcceleratedMotion.CalculateDuration(acceleration, InitialSpeed,
                                                                          distance, ref destinationSpeed, out var accelerationDuration, out var accelerationDistance))
                        {
                            // Max speed will not be reached with current acceleration
                            AccelerationDestination = destination;
                            DestinationSpeed        = destinationSpeed;
                            Duration = AccelerationDuration = accelerationDuration;
                        }
                        else
                        {
                            // Calculate mixed duration of accelerated and linear movements
                            AccelerationDestination = InitialPosition +
                                                      (destination - InitialPosition).normalized * accelerationDistance;
                            var linearDistance = distance - accelerationDistance;
                            AccelerationDuration = accelerationDuration;
                            Duration             = AccelerationDuration + linearDistance / DestinationSpeed;
                        }
                    }
コード例 #2
0
    public void SetFollowWaypoints(List <DriveWaypoint> waypoints, bool loop, WaypointsPathType pathType)
    {
        InitPos = transform.position;
        InitRot = transform.rotation;

        WaypointLoop = loop;
        PathType     = pathType;

        // Process waypoints according to the selected waypoint path
        switch (PathType)
        {
        case WaypointsPathType.Linear:
            break;

        case WaypointsPathType.BezierSpline:
            // Disable BezierSpline if timestamps are set
            if (waypoints[0].TimeStamp >= 0.0f)
            {
                Debug.LogError("Bezier Spline path is not supported if the timestamps are set in the waypoints.");
                PathType = WaypointsPathType.Linear;
                break;
            }

            // Add the initial position for Bezier Spline calculations
            var initWaypoint = ((IWaypoint)waypoints[0]).Clone();
            initWaypoint.Position = InitPos;
            waypoints.Insert(0, (DriveWaypoint)initWaypoint);
            var bezier = new BezierSpline <DriveWaypoint>(waypoints.ToArray(), 0.01f);
            waypoints = bezier.GetBezierWaypoints();

            // Remove first waypoint as it will be added by another function
            waypoints.RemoveAt(0);
            break;

        default:
            throw new ArgumentOutOfRangeException(nameof(PathType), PathType, null);
        }

        LaneData            = waypoints.Select(wp => wp.Position).ToList();
        LaneSpeed           = waypoints.Select(wp => wp.Speed).ToList();
        LaneAcceleration    = waypoints.Select(wp => wp.Acceleration).ToList();
        LaneAngle           = waypoints.Select(wp => Quaternion.Euler(wp.Angle)).ToList();
        LaneIdle            = waypoints.Select(wp => wp.Idle).ToList();
        LaneDeactivate      = waypoints.Select(wp => wp.Deactivate).ToList();
        LaneTriggerDistance = waypoints.Select(wp => wp.TriggerDistance).ToList();
        LaneTime            = waypoints.Select(wp => wp.TimeStamp).ToList();
        LaneTriggers        = waypoints.Select(wp => wp.Trigger).ToList();

        InitNPC();
        AddPoseToFirstWaypoint();

        // Check if the timestamps should be replaced by calculations
        if (LaneTime[1] < 0.0f)
        {
            Debug.LogWarning("Waypoint timestamps absent or invalid, calculating timestamps based on speed and acceleration.");

            // Calculate acceleration data only if there are no timestamps
            for (int i = 0; i < LaneData.Count - 1; i++)
            {
                var   initialPosition  = LaneData[i];
                var   destination      = LaneData[i + 1];
                var   initialSpeed     = LaneSpeed[i];
                var   destinationSpeed = LaneSpeed[i + 1];
                var   distance         = Vector3.Distance(initialPosition, destination);
                float duration;
                if (LaneAcceleration[i + 1] > 0)
                {
                    // If max speed is lower than the initial speed convert acceleration to deceleration
                    if (destinationSpeed < initialSpeed)
                    {
                        LaneAcceleration[i + 1] *= -1;
                    }

                    if (!UniformlyAcceleratedMotion.CalculateDuration(LaneAcceleration[i + 1], initialSpeed,
                                                                      distance, ref destinationSpeed, out var accelerationDuration, out var accelerationDistance))
                    {
                        // Max speed will not be reached with current acceleration
                        AccelerationDestination.Add(destination);
                        LaneSpeed[i + 1] = destinationSpeed;
                        duration         = accelerationDuration;
                        AccelerationDuration.Add(accelerationDuration);
                    }
                    else
                    {
                        // Calculate mixed duration of accelerated and linear movements
                        var accelerationDestination = initialPosition +
                                                      (destination - initialPosition).normalized * accelerationDistance;
                        AccelerationDestination.Add(accelerationDestination);
                        var linearDistance = distance - accelerationDistance;
                        AccelerationDuration.Add(accelerationDuration);
                        duration = accelerationDuration + linearDistance / destinationSpeed;
                    }
                }
                else
                {
                    // There is no acceleration - apply max speed for uniform linear movement
                    AccelerationDuration.Add(0.0f);
                    AccelerationDestination.Add(initialPosition);
                    duration = distance / destinationSpeed;
                }

                // Set waypoint time base on speed.
                LaneTime[i + 1] = LaneTime[i] + duration;
            }
コード例 #3
0
    public void SetFollowWaypoints(List <WalkWaypoint> waypoints, bool loop, WaypointsPathType pathType)
    {
        InitPos = transform.position;
        InitRot = transform.rotation;

        WaypointLoop = loop;
        PathType     = pathType;

        // Process waypoints according to the selected waypoint path
        switch (PathType)
        {
        case WaypointsPathType.Linear:
            break;

        case WaypointsPathType.BezierSpline:
            // Add the initial position for Bezier Spline calculations
            var initWaypoint = ((IWaypoint)waypoints[0]).Clone();
            initWaypoint.Position = InitPos;
            waypoints.Insert(0, (WalkWaypoint)initWaypoint);
            var bezier = new BezierSpline <WalkWaypoint>(waypoints.ToArray(), 0.01f);
            waypoints = bezier.GetBezierWaypoints();

            // Remove first waypoint as it will be added by another function
            waypoints.RemoveAt(0);
            break;

        default:
            throw new ArgumentOutOfRangeException(nameof(PathType), PathType, null);
        }

        LaneData            = waypoints.Select(wp => wp.Position).ToList();
        LaneSpeed           = waypoints.Select(wp => wp.Speed).ToList();
        LaneAcceleration    = waypoints.Select(wp => wp.Acceleration).ToList();
        LaneAngle           = waypoints.Select(wp => Quaternion.Euler(wp.Angle)).ToList();
        LaneIdle            = waypoints.Select(wp => wp.Idle).ToList();
        LaneTriggerDistance = waypoints.Select(wp => wp.TriggerDistance).ToList();
        LaneTriggers        = waypoints.Select(wp => wp.Trigger).ToList();
        LaneTime            = new List <float>();

        InitPedestrian();
        AddPoseToFirstWaypoint();

        // Calculate acceleration data only if there are no timestamps
        for (int i = 0; i < LaneData.Count - 1; i++)
        {
            var   initialPosition  = LaneData[i];
            var   destination      = LaneData[i + 1];
            var   initialSpeed     = LaneSpeed[i];
            var   destinationSpeed = LaneSpeed[i + 1];
            var   distance         = Vector3.Distance(initialPosition, destination);
            float duration;
            if (LaneAcceleration[i + 1] > 0)
            {
                // If max speed is lower than the initial speed convert acceleration to deceleration
                if (destinationSpeed < initialSpeed)
                {
                    LaneAcceleration[i + 1] *= -1;
                }

                if (!UniformlyAcceleratedMotion.CalculateDuration(LaneAcceleration[i + 1], initialSpeed,
                                                                  distance, ref destinationSpeed, out var accelerationDuration, out var accelerationDistance))
                {
                    // Max speed will not be reached with current acceleration
                    AccelerationDestination.Add(destination);
                    LaneSpeed[i + 1] = destinationSpeed;
                    duration         = accelerationDuration;
                    AccelerationDuration.Add(accelerationDuration);
                }
                else
                {
                    // Calculate mixed duration of accelerated and linear movements
                    var accelerationDestination = initialPosition +
                                                  (destination - initialPosition).normalized * accelerationDistance;
                    AccelerationDestination.Add(accelerationDestination);
                    var linearDistance = distance - accelerationDistance;
                    AccelerationDuration.Add(accelerationDuration);
                    duration = accelerationDuration + linearDistance / destinationSpeed;
                }
            }