Beispiel #1
0
        /// <summary>
        /// Perform a deep copy of another general vehicle.
        /// </summary>
        /// <param name="that">Copied general vehicle.</param>
        /// <param name="copytrajectory">If true, the vehicle historic trajectory is copied. Relatively heavy operation.</param>
        protected Vehicle(Vehicle <MeasurerT, PoseT, MeasurementT> that, bool copytrajectory = false)
            : this(that.Pose)
        {
            this.Pose               = that.Pose.DClone();
            this.Graphics           = that.Graphics;
            this.MappedMeasurements = that.MappedMeasurements;
            this.Landmarks          = that.Landmarks;
            this.Measurer           = that.Measurer;
            this.KnowsGroundtruth   = that.KnowsGroundtruth;
            this.Groundtruth        = that.Groundtruth;
            this.HasDataAssociation = that.HasDataAssociation;
            this.DataAssociation    = that.DataAssociation;

            this.motionCovariance      = that.motionCovariance.MemberwiseClone();
            this.MeasurementCovariance = that.MeasurementCovariance.MemberwiseClone();

            if (copytrajectory)
            {
                this.WayPoints      = new TimedState(that.WayPoints);
                this.WayOdometry    = new TimedArray(that.WayOdometry);
                this.WayVisibleMaps = new TimedMapModel(that.WayVisibleMaps);
            }
            else
            {
                this.WayOdometry    = new TimedArray();
                this.WayPoints      = new TimedState();
                this.WayVisibleMaps = new TimedMapModel();

                this.WayPoints.Add(Tuple.Create(0.0, Util.SClone(Pose.State)));
                this.WayVisibleMaps.Add(Tuple.Create(0.0, new Map(3)));
            }
        }
Beispiel #2
0
        /// <summary>
        /// Construct a Navigator using the indicated vehicle as a reference.
        /// </summary>
        /// <param name="vehicle">Vehicle to track.</param>
        /// <param name="onlymapping">If true, don't do SLAM, but mapping (i.e. the localization is assumed known).</param>
        protected Navigator(Vehicle <MeasurerT, PoseT, MeasurementT> vehicle, bool onlymapping = false)
        {
            OnlyMapping = onlymapping;

            // a reference copy, which gives the navigator precise info about
            // the real vehicle pose
            RefVehicle = vehicle;

            WayTrajectories = new TimedTrajectory();
            WayTrajectories.Add(Tuple.Create(0.0, new TimedState {
                Tuple.Create(0.0, Util.SClone(vehicle.Pose.State))
            }));

            WayMaps = new TimedMapModel();
            WayMaps.Add(Tuple.Create(0.0, new Map(3)));

            const int segments = 32;

            pinterval = new double[segments][];

            // pinterval will be the 5-sigma ellipse
            for (int i = 0; i < segments; i++)
            {
                pinterval[i] = new double[2] {
                    5 * Math.Cos(2 * Math.PI * i / segments), 5 * Math.Sin(2 * Math.PI * i / segments)
                };
            }
        }
Beispiel #3
0
        /// <summary>
        /// Construct a new Vehicle object from its initial state and appropiate constants.
        /// </summary>
        /// <param name="initial">Initial pose.</param>
        /// <param name="measurer">Measuring config and methods.</param>
        protected Vehicle(PoseT initial, MeasurerT measurer)
        {
            Pose     = initial.DClone();
            Measurer = measurer;

            OdometryPose = Pose.DClone();
            refodometry  = Pose.DClone();

            HasDataAssociation = false;
            DataAssociation    = new List <int>();
            Landmarks          = new List <double[]>();
            MappedMeasurements = new List <double[]>();

            Groundtruth      = new TimedState();
            KnowsGroundtruth = false;

            WayOdometry    = new TimedArray();
            WayPoints      = new TimedState();
            WayVisibleMaps = new TimedMapModel();

            WayPoints.Add(Tuple.Create(0.0, Util.SClone(Pose.State)));
            WayVisibleMaps.Add(Tuple.Create(0.0, new Map(3)));

            HasSidebar   = false;
            WantsToStop  = false;
            WantsSLAM    = false;
            WantsMapping = false;
        }
Beispiel #4
0
        /// <summary>
        /// Obtain the cumulative odometry reading since the last call to this function.
        /// Note that this version doesn't actually "reset" the odometry
        /// and gives the discrete recorded points in the odometry file.
        /// Calling multiple times this function would give the same result, even
        /// if the base behavior would be to return zero after the first time.
        /// </summary>
        /// <returns>State diff.</returns>
        public override double[] ReadOdometry(GameTime time)
        {
            double[] odometry = Odometry[FrameIndex].Item2;

            WayOdometry.Add(Tuple.Create(time.TotalGameTime.TotalSeconds, Util.SClone(odometry)));

            return(odometry);
        }
Beispiel #5
0
        /// <summary>
        /// Remove all the localization and mapping history and start it again from the current position.
        /// </summary>
        public virtual void ResetHistory()
        {
            WayTrajectories.Clear();
            WayMaps.Clear();

            WayTrajectories.Add(Tuple.Create(0.0, new TimedState {
                Tuple.Create(0.0, Util.SClone(BestEstimate.Pose.State))
            }));
            WayMaps.Add(Tuple.Create(0.0, new Map(3)));
        }
Beispiel #6
0
        /// <summary>
        /// Obtain the cumulative odometry reading since the last call to this function.
        /// </summary>
        /// <returns>State diff.</returns>
        public virtual double[] ReadOdometry(GameTime time)
        {
            double[] reading = OdometryPose.DiffOdometry(refodometry);

            OdometryPose = Pose.DClone();
            refodometry  = Pose.DClone();

            WayOdometry.Add(Tuple.Create(time.TotalGameTime.TotalSeconds, Util.SClone(reading)));

            return(reading);
        }
Beispiel #7
0
        /// <summary>
        /// Apply the motion model to the vehicle. It corresponds to a
        /// 3D odometry model following the equation:
        ///
        /// x = x + q dx q* + N(0, Q)
        /// o = dq o dq* + N(0, Q')
        ///
        /// where q is the midrotation quaternion (halfway between the old and new orientations) and N(a, b) is a normal function
        /// with mean 'a' and covariance matrix 'b'.
        /// </summary>
        /// <param name="time">Provides a snapshot of timing values.</param>
        /// <param name="reading">Odometry reading (dx, dy, dz, dpitch, dyaw, droll).</param>
        public virtual void Update(GameTime time, double[] reading)
        {
            Pose         = Pose.AddOdometry(reading);
            OdometryPose = OdometryPose.AddOdometry(reading);

            double[] noise = time.ElapsedGameTime.TotalSeconds.Multiply(
                Util.RandomGaussianVector(new double[OdoSize],
                                          MotionCovariance));
            OdometryPose = OdometryPose.AddOdometry(noise);

            WayPoints.Add(Tuple.Create(time.TotalGameTime.TotalSeconds, Util.SClone(Pose.State)));
        }
Beispiel #8
0
        /// <summary>
        /// Calculate the transpose of a vector (a horizontal matrix).
        /// </summary>
        /// <param name="vector">Vector to be transposed.</param>
        /// <param name="shallow">If true, use the same vector for the matrix,
        /// but changing values in one will be reflected on the other.</param>
        /// <returns>Transposed vector.</returns>
        public static double[][] Transpose(this double[] vector, bool shallow = false)
        {
            double[][] result = new double[1][];

            if (shallow)
            {
                result[0] = vector;
            }
            else
            {
                result[0] = Util.SClone(vector);
            }

            return(result);
        }
Beispiel #9
0
        /// <summary>
        /// Apply the motion model to the vehicle. It corresponds to a
        /// 3D odometry model following the equation:
        ///
        /// x = x + q dx q*
        /// o = dq o dq*
        ///
        /// where q is the midrotation quaternion (halfway between the old and new orientations) and N(a, b) is a normal function
        /// with mean 'a' and covariance matrix 'b'.
        /// </summary>
        /// <param name="time">Provides a snapshot of timing values.</param>
        /// <param name="reading">Odometry reading (dx, dy, dz, dpitch, dyaw, droll).</param>
        public override void Update(GameTime time, double[] reading)
        {
            // no input, static friction makes the robot stay put (if there is any static friction)
            if (PerfectStill && reading.IsEqual(0))
            {
                Pose         = Pose.AddOdometry(reading);
                OdometryPose = OdometryPose.AddOdometry(reading);

                WayPoints.Add(Tuple.Create(time.TotalGameTime.TotalSeconds, Util.SClone(Pose.State)));
            }
            else
            {
                base.Update(time, reading);
            }
        }
Beispiel #10
0
        /// <summary>
        /// Construct a RecordVehicle from prerecorded data.
        /// </summary>
        /// <param name="trajectory">Prerecorded trajectory.</param>
        /// <param name="odometry">Prerecorded odometry.</param>
        /// <param name="measurements">Prerecorded measurements.</param>
        /// <param name="tags">Prerecorded tags.</param>
        /// <param name="landmarks">Landmark 3d locations against which the measurements were performed.</param>
        /// <param name="measurer">Measuring config and methods.</param>
        public RecordVehicle(TimedState trajectory, TimedArray odometry,
                             TimedMeasurements measurements, TimedMessage tags,
                             List <double[]> landmarks, MeasurerT measurer)
            : base(new PoseT().IdentityP(), measurer)
        {
            if (trajectory.Count != measurements.Count + 1)
            {
                throw new ArgumentException("Measurements length must be one short of the trajectory length.");
            }

            if (trajectory.Count != odometry.Count + 1)
            {
                throw new ArgumentException("Odometry length must be one short of the trajectory length.");
            }

            if (trajectory.Count < 1)
            {
                throw new ArgumentException("Trajectory length must be positive");
            }

            Groundtruth  = trajectory;
            Odometry     = new TimedState(odometry);
            Measurements = new TimedMeasurements(measurements);
            Tags         = tags;

            Odometry.Insert(0, Tuple.Create(0.0, new double[OdoSize]));
            Measurements.Insert(0, Tuple.Create(0.0, new List <double[]>()));

            RecLength  = Trajectory.Count;
            FrameIndex = 0;

            updateWants();
            FrameIndex = 1;

            Landmarks = landmarks;
            Pose      = new PoseT().FromState(Trajectory[0].Item2);

            WayPoints.Clear();
            WayPoints.Add(Tuple.Create(0.0, Util.SClone(Pose.State)));
        }
Beispiel #11
0
 /// <summary>
 /// Remove all the localization history and start it again from the current position.
 /// </summary>
 public void ResetHistory()
 {
     WayOdometry.Clear();
     WayPoints.Clear();
     WayPoints.Add(Tuple.Create(0.0, Util.SClone(Pose.State)));
 }
Beispiel #12
0
        /// <summary>
        /// Apply the motion model to the vehicle. It corresponds to a
        /// 3D odometry model following the equation:
        ///
        /// x = x + q dx q* + N(0, Q)
        /// o = dq o dq* + N(0, Q')
        ///
        /// where q is the midrotation quaternion (halfway between the old and new orientations) and N(a, b) is a normal function
        /// with mean 'a' and covariance matrix 'b'.
        /// </summary>
        /// <param name="time">Provides a snapshot of timing values.</param>
        /// <param name="reading">Odometry reading (dx, dy, dz, dpitch, dyaw, droll).</param>
        public void UpdateNoisy(GameTime time, double[] reading)
        {
            Update(time, reading);

            // no input, static friction makes the robot stay put (if there is any static friction)
            if (!(PerfectStill && reading.IsEqual(0)))
            {
                double[] noise = time.ElapsedGameTime.TotalSeconds.Multiply(
                    Util.RandomGaussianVector(new double[OdoSize],
                                              MotionCovariance));
                Pose = Pose.AddOdometry(noise);
            }

            WayPoints[WayPoints.Count - 1] = Tuple.Create(time.TotalGameTime.TotalSeconds, Util.SClone(Pose.State));
        }
Beispiel #13
0
 /// <summary>
 /// Apply the motion model to the vehicle.
 /// </summary>
 /// <param name="time">Provides a snapshot of timing values.</param>
 /// <param name="reading">Odometry reading (dx, dy, dz, dpitch, dyaw, droll).</param>
 public override void Update(GameTime time, double[] reading)
 {
     Pose = new PoseT().FromState(Trajectory[FrameIndex].Item2);
     WayPoints.Add(Tuple.Create(time.TotalGameTime.TotalSeconds, Util.SClone(Pose.State)));
 }