Beispiel #1
0
        /// <summary>
        /// Add the EKF.
        /// 追加
        /// </summary>
        /// <param name="q">Q.</param>
        /// <param name="error">Error.</param>
        /// <param name="points">Points.</param>
        /// <param name="Descriptors">Descriptors.</param>
        public IEnumerator AddEnumerator(Quaternion q, float error, IList <Vector3> points, MatOfFloat Descriptors)
        {
            _updateStatus = true;
            if (points.Count != Descriptors.rows())
            {
                throw new OutLookARException("KeyVectorとDescriptorsの数が合いません");
            }
            int nowSize     = StateMatrix.rows();
            int N           = (nowSize - 4) / 3;
            int pointsCount = points.Count;
            int newSize     = nowSize + pointsCount * 3;

            Mat uStateMatrix = g(StateMatrix, q);

            uStateMatrix = uStateMatrix.resize(newSize);
            yield return(null);

            Mat uVarianceCovarianceMatrix = G(N) * VarianceCovarianceMatrix * GT(N) + FxT(N) * R(error) * Fx(N);

            uVarianceCovarianceMatrix = uVarianceCovarianceMatrix.resize(newSize, newSize);
            for (int i = 0; i < pointsCount; i++)
            {
                for (int c = 0; c < 3; c++)
                {
                    uVarianceCovarianceMatrix.put(nowSize + c + 3 * i, nowSize + c + 3 * i, Infinite);
                }
                yield return(null);
            }
            Mat        I = Mat.eye(newSize, newSize, Type);
            Quaternion uStateMatrix_q = new Quaternion((float)uStateMatrix.get(0, 0)[0], (float)uStateMatrix.get(1, 0)[0], (float)uStateMatrix.get(2, 0)[0], (float)uStateMatrix.get(3, 0)[0]);
            int        j = N + 1;

            foreach (Vector3 point in points)
            {
                Vector3 uStateMatrix_j = uStateMatrix_q * point;
                uStateMatrix.put(j * 3 + 1, 0, uStateMatrix_j.x);
                uStateMatrix.put(j * 3 + 2, 0, uStateMatrix_j.y);
                uStateMatrix.put(j * 3 + 3, 0, uStateMatrix_j.z);
                Mat h = H(uStateMatrix_j, uStateMatrix_q) * FxJ(j, N + pointsCount);
                Mat K = uVarianceCovarianceMatrix * h.t() * (h * uVarianceCovarianceMatrix * h.t() + Q).inv();
                uVarianceCovarianceMatrix = (I - K * h) * uVarianceCovarianceMatrix;

                yield return(null);

                j++;
            }
            _stateMatrix = uStateMatrix;
            _varianceCovarianceMatrix = uVarianceCovarianceMatrix;
            _stateDescriptors.Add(Descriptors);
            _updateStatus = false;
        }
        public IEnumerator UpdateMap(IList <Vector3> KeyVector, MatOfFloat Descriptors)
        {
            float MinError = 500f;

            if (UpdateMapFlag)
            {
                throw new OutLookARException("Map更新中です。");
            }
            if (!initFlag)
            {
                throw new OutLookARException("初期化されていません");
            }
            if (KeyVector.Count != Descriptors.rows() || Descriptors.rows() <= 0)
            {
                throw new OutLookARException("KeyVectorとDescriptorsの数が合いません");
            }
            updateMapFlag = true;
            Debug.Log("Update Start");
            IList <DMatch> matches;

            matches = Utils.CrossMatcher(MapDescriptors, Descriptors).LowPassFilter();
            if (matches.Count <= 0)
            {
                updateMapFlag = false;
                throw new OutLookARException("マッチしませんでした");
            }
            Debug.Log("Updating <1>");
            yield return(null);

            List <int>     IndexL     = new List <int>();
            List <Vector3> FromPointL = new List <Vector3>();
            List <Vector3> ToPointL   = new List <Vector3>();

            for (int i = 0; i < KeyVector.Count; i++)
            {
                IndexL.Add(i);
            }
            Debug.Log("Updating <2>");
            foreach (DMatch match in matches)
            {
                IndexL.Remove(match.trainIdx);
                FromPointL.Add(MapKeyVector[match.queryIdx]);
                ToPointL.Add(KeyVector[match.trainIdx]);
            }
            yield return(null);

            Debug.Log("Updating <3>");
            float      minError;
            Quaternion q = LMedS(FromPointL, ToPointL, out minError);

            Debug.Log(minError);
            if (minError < 10f)
            {
                foreach (int id in IndexL)
                {
                    MapDescriptors.Add(Descriptors.row(id));
                    MapKeyVector.Add(new Quaternion(-q.x, -q.y, -q.z, q.w) * KeyVector[id]);
                    MapError.Add(minError + 10f);
                }
            }
            yield return(null);

            Debug.Log("Updating <4>");
            SortedList <int, int> RemoveIDL = new SortedList <int, int>();

            foreach (DMatch match in matches)
            {
                Vector3 vec      = q * MapKeyVector[match.queryIdx];
                float   distanse = Mathf.Sqrt(Mathf.Pow((vec.x - KeyVector[match.trainIdx].x), 2) + Mathf.Pow((vec.y - KeyVector[match.trainIdx].y), 2) + Mathf.Pow((vec.z - KeyVector[match.trainIdx].z), 2));
                if (distanse > MinError)
                {
                    try
                    {
                        if (MapError[match.queryIdx] > minError)
                        {
                            RemoveIDL.Add(MapKeyVector.Count - match.queryIdx, match.queryIdx);
                        }
                        else if (MapError[match.queryIdx] < minError)
                        {
                            MapKeyVector[match.queryIdx] = (new Quaternion(-q.x, -q.y, -q.z, q.w) * KeyVector[match.trainIdx]);
                            MapError[match.queryIdx]     = minError;
                        }
                    }
                    catch (InvalidCastException e)
                    {
                        Debug.Log(e);
                    }
                }
            }
            yield return(null);

            MatOfFloat MapDescriptorsClone = MapDescriptors.clone() as MatOfFloat;

            foreach (int id in RemoveIDL.Values)
            {
                try
                {
                    MapDescriptorsClone.RemoveAt(id);
                    MapKeyVector.RemoveAt(id);
                    MapError.RemoveAt(id);
                }
                catch (InvalidCastException e)
                {
                    Debug.Log(e);
                }
            }
            MapDescriptorsClone.copyTo(MapDescriptors);
            updateMapFlag = false;
            Debug.Log("Update Comp");
        }