简体   繁体   English

编写 3d 轨迹预测系统

[英]Coding a 3d trajectory prediction system

Alright, so for months (on and off) I've been trying to create a system for a VR game I'm making which will predict where the player is moving their hand based on where it has been in the last dozen or so frames.好吧,所以几个月来(断断续续)我一直在尝试为我正在制作的 VR 游戏创建一个系统,该系统将根据过去十几个帧中的位置预测玩家移动手的位置. I'm fully aware this won't be completely accurate but it doesn't need to be.我完全知道这不会完全准确,但也不必如此。 Irritatingly, no matter what I've tried so far, I am unable to get it working to a sufficient degree.令人恼火的是,到目前为止,无论我尝试了什么,我都无法让它发挥足够的作用。

The idea I've been working off is getting the average direction that the hand has been moving for the last few frames, then working out the average change in those directions, then working out the average change in those directions.我一直在努力的想法是获取手在最后几帧中移动的平均方向,然后计算出这些方向的平均变化,然后计算出这些方向的平均变化。 I then calculate based on the hand's current position where it will be in the next dozen or so frames.然后我根据手的当前 position 计算它在接下来的十几帧中的位置。 I get the next position by, starting with the current position, moving the point in the last known direction (the direction between the current point and the previous point), then taking that direction, rotating it based on the average change in directions, and then, rotating that value by the average changes in those directions.我得到下一个 position,从当前的 position 开始,沿最后一个已知方向(当前点和前一个点之间的方向)移动该点,然后采用该方向,根据方向的平均变化旋转它,并且然后,通过这些方向的平均变化来旋转该值。

I am yet to get this system working and it is beginning to drive me crazy.我还没有让这个系统工作,它开始让我发疯。 Sadly because it could be moving in any direction I can't just use a standard trajectory calculation algorithm and I have to work with Quaternions, which are inherently confusing.可悲的是,因为它可能向任何方向移动,我不能只使用标准的轨迹计算算法,而且我必须使用四元数,这本质上是令人困惑的。

If you're able to assist me with this problem I would be immensely grateful.如果您能够帮助我解决这个问题,我将不胜感激。 Whether it is by helping me with my current method or pointing out a different method.无论是帮助我使用当前的方法还是指出不同的方法。

My current (not working code) is here simply in order to aid in understanding what I'm trying to do.我当前的(不工作的代码)在这里只是为了帮助理解我正在尝试做的事情。

void PredictTrajectory()
{
            Vector3 avgDirection = Vector3.zero;
            List<Vector3> directions = new List<Vector3>();
            Vector3 avgChangeInDirection = Vector3.zero;
            List<Vector3> changeInDirections = new List<Vector3>();
            Vector3 avgChangeInChangeInDirection = Vector3.zero;
            float avgDistanceBetweenPoints = 0;

            for (int index = hand.PastLocations.Length - 1; index > 0; index--)
            {
                avgDirection += (hand.PastLocations[index - 1] - hand.PastLocations[index]).normalized;
                directions.Add((hand.PastLocations[index - 1] - hand.PastLocations[index]).normalized);
                avgDistanceBetweenPoints += Vector3.Distance(hand.PastLocations[index - 1], hand.PastLocations[index]);
            }
            avgDirection.Normalize();
            avgDistanceBetweenPoints /= hand.PastLocations.Length - 1;

            avgDirection = hand.PastLocations[0] - hand.PastLocations[1];
            avgDirection.Normalize();
            
            Quaternion avgDirectionChange = Quaternion.identity;
            List<Quaternion> changesInDirection = new List<Quaternion>();
            for (int index = 0; index < directions.Count - 2; index++)
            {
                changesInDirection.Add(Quaternion.FromToRotation(directions[index], directions[index + 1]));
            }
            avgDirectionChange = changesInDirection.Average();

            Quaternion avgChangeInDirectionChange = Quaternion.identity;
            List<Quaternion> changesInChangeInDirection = new List<Quaternion>();
            for (int index = 0; index < changesInDirection.Count - 2; index++)
            {
                changesInChangeInDirection.Add(changesInDirection[index + 1] * Quaternion.Inverse(changesInDirection[index]));
            }
            avgChangeInDirectionChange = changesInChangeInDirection.Average();
            avgChangeInChangeInDirection.Normalize();

            avgChangeInDirectionChange = Quaternion.FromToRotation(avgChangeInDirection, avgChangeInChangeInDirection);

            List<Vector3> points = new List<Vector3>();
            points.Add(hand.transform.position);
            for (int index = 0; index < 200; index++)
            {
                avgDirection = avgDirectionChange * avgDirection;
                points.Add(points.Last() + (avgDirection * avgDistanceBetweenPoints));
                avgDirectionChange = avgChangeInDirectionChange * avgDirectionChange;
            }

            predictedArc = new Arc(points);
            WorldManager.Instance.DrawPredictionArc(predictedArc);
}

I don't often post here so if I've done so incorrectly I apologise.我不经常在这里发帖,所以如果我做错了,我道歉。

EDIT: So despite my wall of text, I may not have actually said exactly what I want in a concise way so here it is.编辑:所以尽管我的文字墙,我实际上可能并没有以简洁的方式准确地说出我想要的东西,所以就在这里。

I need a function that can semi-accurately predict the future location of an object moving in a non-linear way.我需要一个 function 可以半准确地预测 object 以非线性方式移动的未来位置。 I need it to give me the predicted locations for multiple frames in the future (For example: If I want to predict the next 15 frames, I need to get 15 positions, not 1).我需要它来给我未来多帧的预测位置(例如:如果我想预测接下来的 15 帧,我需要得到 15 个位置,而不是 1 个)。

So, for 15 steps forward in time, you could do this, where speed and acceleration are estimated on the last frame:因此,对于时间向前 15 步,您可以这样做,在最后一帧估计速度和加速度:

Vector3 lastPos = Vector3.zero;
Vector3 velocity = Vector3.zero;
Vector3 lastVelocity = Vector3.zero;
Vector3 acceleration = Vector3.zero;
float stepTime = 0.1f;
int predictionSteps = 15;
Vector3 predictedPos = Vector3.zero;
List<Vector3> futurePositions;
...
void Update()
{
  lastVelocity = velocity;
  velocity = (transform.position - lastPos) / Time.deltaTime;
  lastPos = transform.position;
  acceleration = (velocity - lastVelocity) / Time.deltatime;
  predictedPos = transform.position;
  futurePositions = new List<Vector3>();
  for(int i = 0; i < predictionSteps; i++)
  {
    predictedPos += velocity * stepTime;
    futurePositions.Add(predictedPos);
    velocity += acceleration * stepTime;
  }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM