示例#1
0
        public Plane(DVector pointA, DVector pointB, DVector pointC)
        {
            var u = pointC - pointA;
            var v = pointC - pointB;

            this.Normal      = (DVector)CrossProduct(u, v).Normalize(3);
            this.PlanarPoint = pointA;
        }
示例#2
0
        public KalmanFilter(KalmanSetup setup)
        {
            this.stdDevProcess     = setup.StdDevProcess;
            this.stdDevMeasurement = setup.StdDevMeasurement;
            this.X = setup.X0;
            this.P = setup.P0;
            this.H = setup.H;

            this.F = setup.funcF;
            this.B = setup.funcB;
            this.Q = setup.funcQ;
            this.R = setup.funcR(stdDevMeasurement);
        }
示例#3
0
        public Vector Update(float dt, Vector measurement, Vector controlInput)
        {
            // Predict
            this.X = PredictState(dt, controlInput);
            this.P = PredictCovariance(dt);

            // Update
            var y = MeasurementResidual(measurement);
            var S = CovarianceResidual();
            var K = KalmanGain(S);

            this.X = StateEstimation(K, y);
            this.P = CovarianceEstimation(K);

            return(this.X);
        }
示例#4
0
文件: SvdSolver.cs 项目: KFlaga/Cam3D
        public static Vector<float> Solve(Matrix<float> A, Vector<float> b)
        {
            MathNet.Numerics.LinearAlgebra.Factorization.Svd<float> svd = A.Svd();

            double dmax = svd.S[0];
            Vector<float> y = new MathNet.Numerics.LinearAlgebra.Single.DenseVector(A.ColumnCount);
            Vector<float> bp = svd.U.Transpose() * b;

            // TODO: use the fact that S is sorted ( while S[i]/dmax < e then assume its greater )
            int minSize = Math.Min(A.ColumnCount, A.RowCount);
            for(int i = 0; i < minSize; ++i)
            {
                if(svd.S[i] / dmax < 1e-16)
                {
                    y[i] = 0.0f;
                }
                else
                {
                    y[i] = bp[i] / svd.S[i];
                }
            }

            return svd.VT.Transpose() * y;
        }
示例#5
0
 private Vector StateEstimation(Matrix kalmanGain, Vector measurementResidual)
 {
     return(X + kalmanGain * measurementResidual);
 }
示例#6
0
 private Vector MeasurementResidual(Vector measurement)
 {
     return(measurement - H * X);
 }
示例#7
0
 private Vector PredictState(float dt, Vector controlInput)
 {
     return(F(dt) * X + B(dt) * controlInput);
 }
示例#8
0
 public MvaWacohForceVector(MathNet.Numerics.LinearAlgebra.Single.DenseVector vec)
     : base(vec.ToArray())
 {
 }
示例#9
0
        public static async Task <PointCloud> GenerateObject(Recording recording, IProgress <int> progress, CancellationToken ct)
        {
            // Quick access image formats
            var dFormat = recording.DepthFormat;
            var cFormat = recording.ColourFormat;

            #region Check for calibration data
            if (!recording.IsCalibratedRecording)
            {
                throw new IOException("Pre-calibrated recording required!");
            }
            var calibration = recording.Calibration;
            #endregion

            #region Kalman Filter setup
            var kSetup = new KalmanSetup()
            {
                funcF = new Func <float, Matrix>(FGenerator),
                funcB = new Func <float, Matrix>(BGenerator),
                H     = Matrix.OfArray(new float[, ] {
                    { 1, 0 }
                }),
                X0 = new Vector(new float[] { 0, 0 }),
                P0 = Matrix.OfArray(new float[, ] {
                    { 10, 0 }, { 0, 10 }
                }),
                funcQ             = new Func <float, float, Matrix>(QGenerator),
                funcR             = new Func <float, Matrix>(RGenerator),
                StdDevMeasurement = stdDevMeasurementNoise,
                StdDevProcess     = stdDevProcessNoise
            };
            float R   = calibration.TurntableRadius;
            float acc = -4 * mu * g / (3 * R);
            var   accelerationVector = new Vector(new float[] { acc });
            #endregion

            #region Initialise pipeline stages
            var cv   = new HueThresholder(calibration.Markers, calibration.MarkerSearchSpace);
            var geom = new PointCloudBuilder(calibration, recording.MappingParameters);
            var kf   = new KalmanFilter(kSetup);
            var opt  = new ICPMinimiser(true);
            #endregion

            // start new pipeline thread
            return(await Task.Run <PointCloud>(() =>
            {
                var returnCloud = new PointCloud();
                PointCloud prevCloud = null;
                float lastTime = 0;
                double theta = 0;
                Point3D lastx = new Point3D(0, 0, 0);

                int advanceUnit = Processing.Settings.Default.ProcessEveryFrame ? 1 : 10;

                #region KF Debug Logging
                StreamWriter filterLog = null;
                if (DebugSettings.Default.DebugMode)
                {
                    filterLog = new StreamWriter(DebugSettings.Default.LogRoot + @"\filter.csv");
                    filterLog.AutoFlush = true;
                    filterLog.WriteLine("t,dt,dx,dtheta,theta,theta_KF,omega_KF");
                }
                #endregion

                for (int i = 0; i < recording.NumberOfFrames; i += advanceUnit)
                {
                    ct.ThrowIfCancellationRequested();
                    progress.Report(i);

                    #region Fetch
                    // Fetch frame from disk
                    float timestamp = recording.Timestamps[i];
                    var colour = recording.FetchColourFrame(i);
                    var depth = recording.FetchDepthFrame(i);
                    Frame f = new Frame(i, timestamp, depth, dFormat, colour, cFormat);
                    #endregion

                    #region Analyse (CV)
                    var markers2D = cv.IdentifyMarkers(f);
                    if (markers2D.Count == 0)
                    {
                        i -= (advanceUnit - 1);
                        continue;
                    }
                    #endregion

                    #region Build Geometry (GEOM)
                    PointCloud cloud;
                    KeyValuePair <TrackingMarker, Point3D> rotationMarker;
                    var geomSuccess = geom.ConstructCloud(f, markers2D, out cloud, out rotationMarker);
                    if (!geomSuccess)
                    {
                        i -= (advanceUnit - 1);
                        continue;
                    }
                    #endregion

                    #region Filter
                    // reposition marker based on offset
                    var polarX = CoordinateSystemConvertor.ToSpherical(rotationMarker.Value);
                    polarX.Azimuthal += (float)rotationMarker.Key.RotationalOffset;
                    var x = CoordinateSystemConvertor.ToCartesian(polarX);

                    // rotation approximation
                    var dx = ((Vector)x - lastx).Norm(3);
                    var dtheta = dx / calibration.TurntableRadius;

                    // update cumulative angle (with estimated angle)
                    theta += dtheta;

                    // calculate time delta
                    float dt = f.Timestamp - lastTime;

                    if (DebugSettings.Default.DebugMode)
                    {
                        filterLog.Write("{0},{1},{2},{3},{4},", f.Timestamp, dt, dx, dtheta, theta);
                    }

                    // calculate state vector
                    var stateVector = new Vector(new float[] { (float)theta });

                    // pass through kalman filter
                    var filteredStateVector = kf.Update(dt, stateVector, accelerationVector);

                    // extract angle from state vector
                    var filteredTheta = filteredStateVector[0];
                    var filteredOmega = filteredStateVector[1];

                    if (DebugSettings.Default.DebugMode)
                    {
                        filterLog.WriteLine("{0},{1}", filteredTheta, filteredOmega);
                    }

                    // update last time, last position and set filtered cumulative theta
                    theta = filteredTheta;
                    lastx = x;
                    lastTime = f.Timestamp;

                    #endregion

                    #region Optimise (OPT)
                    PointCloud optCloud = null;
                    if (prevCloud == null)
                    {
                        optCloud = cloud;     // first frame; this is requires no optimising transformation
                    }
                    else if (prevCloud.Points.Count == 0)
                    {
                        optCloud = cloud;     // no points in previous cloud (model); cannot align the current cloud to model
                    }
                    else
                    {
                        // Build best guess transformation matrix
                        float sinT = (float)Math.Sin(filteredTheta);
                        float cosT = (float)Math.Cos(filteredTheta);
                        var bestGuessTransformation = Matrix.Identity(4);
                        bestGuessTransformation[0, 0] = cosT;
                        bestGuessTransformation[0, 2] = -sinT;
                        bestGuessTransformation[2, 0] = sinT;
                        bestGuessTransformation[2, 2] = cosT;
                        // returned object is result of aligning cloud with prevCloud
                        optCloud = opt.Process(cloud, prevCloud, bestGuessTransformation);
                    }
                    prevCloud = cloud;
                    #endregion

                    #region Retire
                    returnCloud.Points.AddRange(optCloud.Points);
                    #endregion
                }

                if (DebugSettings.Default.DebugMode)
                {
                    filterLog.Close();
                }
                return returnCloud;
            }));
        }
示例#10
0
 public Plane(DVector normal, DVector pointInThePlane)
 {
     this.Normal      = (DVector)normal.Normalize(3);
     this.PlanarPoint = pointInThePlane;
 }