コード例 #1
0
        private async Task GoTo(GeoPoint location, MavFrame frame, CancellationToken cancel, double?yawDeg = null, double?vx = null, double?vy = null, double?vz = null)
        {
            await EnsureInGuidedMode(cancel);

            if (location.Altitude.HasValue == false)
            {
                throw new MavlinkException(RS.VehicleArdupilot_GoTo_Altitude_of_end_point_is_null);
            }

            var yaw = yawDeg.HasValue ? (float?)GeoMath.DegreesToRadians(yawDeg.Value) : null;
            await Mavlink.Common.SetPositionTargetGlobalInt(0, frame, cancel, (int)(location.Latitude * 10000000), (int)(location.Longitude * 10000000), (float)location.Altitude.Value, yaw : yaw);
        }
コード例 #2
0
        public override async Task FlyByLineGlob(GeoPoint start, GeoPoint stop, double precisionMet, CancellationToken cancel, Action firstPointComplete = null)
        {
            const int    ApproachAngle         = 90;
            const int    PrePointDistanceParts = 2;
            const double GoToPrecisionErrorMet = 20.5;

            var waitForDetectingAzimuthTime = TimeSpan.FromSeconds(3);
            var waitInPrePointTime          = TimeSpan.FromSeconds(3);
            var waitForCorrectionTime       = TimeSpan.FromSeconds(1);

            var start0 = start.SetAltitude(0);
            var stop0  = stop.SetAltitude(0);

            var azimuth          = start0.Azimuth(stop0);
            var reverseAzimuth   = stop0.Azimuth(start0);
            var loiterRadius     = (_planeRadius.Value ?? await _planeRadius.FirstAsync(_ => _.HasValue)).Value;
            var realLoiterRadius = (int)(loiterRadius + GoToPrecisionErrorMet);



            var startPrePoint0          = start0.RadialPoint(PrePointDistanceParts * realLoiterRadius, reverseAzimuth);
            var pointDistanceFromGround = GeoMath.Distance(start0, stop0);
            var angle = Math.Abs(pointDistanceFromGround) > 0.001 ? GeoMath.RadiansToDegrees(Math.Atan(Math.Abs((start.Altitude) - (stop.Altitude)) / pointDistanceFromGround)) : 0.0;

            var height = GeoMath.HeightFromGroundRange(GeoMath.Distance(stop0, startPrePoint0), angle);

            if ((start.Altitude) - (stop.Altitude) < 0)
            {
                height = (stop.Altitude) - height;
            }
            else
            {
                height = (stop.Altitude) + height;
            }

            //TODO if (height <= 0) нужно что-то делать!!!
            if (height <= 0)
            {
                _logger.Info($"Impossible fly by line from altitude {start.Altitude}м to altitude {stop.Altitude}m");
                return;
            }

            var firstPrePoint = startPrePoint0.RadialPoint(PrePointDistanceParts * realLoiterRadius, azimuth + ApproachAngle).SetAltitude(height);

            var r = await GoToPointUntilReachAzimuth(firstPrePoint, reverseAzimuth - 10, realLoiterRadius, 4, cancel, 2).ConfigureAwait(false);

            var secondPrePoint = startPrePoint0.RadialPoint(r, azimuth + ApproachAngle).SetAltitude(height);

            await GoToPointUntilReachAzimuth(secondPrePoint, reverseAzimuth + ApproachAngle - 10, realLoiterRadius, 2, cancel, 2).ConfigureAwait(false);
            await GoToGlobAndWait(stop, CallbackProgress <double> .Default, realLoiterRadius, cancel).ConfigureAwait(false);
        }
コード例 #3
0
        protected virtual void InitHome()
        {
            _mavlink.Rtt.RawHome
            .Select(_ => (GeoPoint?)new GeoPoint(_.Latitude / 10000000D, _.Longitude / 10000000D, _.Altitude / 1000D))
            .Subscribe(_home, DisposeCancel.Token);
            DisposeCancel.Token.Register(() => _homeDistance.Dispose());

            this.GlobalPosition
            .Where(_ => _home.Value.HasValue)
            // ReSharper disable once PossibleInvalidOperationException
            .Select(_ => (double?)GeoMath.Distance(_home.Value.Value, _))
            .Subscribe(_homeDistance, DisposeCancel.Token);
            DisposeCancel.Token.Register(() => _home.Dispose());
        }
コード例 #4
0
        protected virtual void InitAttitude()
        {
            _mavlink.Rtt.RawAttitude.Select(_ => (double)GeoMath.RadiansToDegrees(_.Pitch)).Subscribe(_pitch, DisposeCancel.Token);
            _mavlink.Rtt.RawAttitude.Select(_ => (double)GeoMath.RadiansToDegrees(_.Roll)).Subscribe(_roll, DisposeCancel.Token);
            _mavlink.Rtt.RawAttitude.Select(_ => (double)GeoMath.RadiansToDegrees(_.Yaw)).Subscribe(_yaw, DisposeCancel.Token);
            _mavlink.Rtt.RawAttitude.Select(_ => (double)_.Pitchspeed).Subscribe(_pitchSpeed, DisposeCancel.Token);
            _mavlink.Rtt.RawAttitude.Select(_ => (double)_.Rollspeed).Subscribe(_rollSpeed, DisposeCancel.Token);
            _mavlink.Rtt.RawAttitude.Select(_ => (double)_.Yawspeed).Subscribe(_yawSpeed, DisposeCancel.Token);

            DisposeCancel.Token.Register(() => _pitch.Dispose());
            DisposeCancel.Token.Register(() => _roll.Dispose());
            DisposeCancel.Token.Register(() => _yaw.Dispose());
            DisposeCancel.Token.Register(() => _pitchSpeed.Dispose());
            DisposeCancel.Token.Register(() => _rollSpeed.Dispose());
            DisposeCancel.Token.Register(() => _yawSpeed.Dispose());
        }
コード例 #5
0
        public async Task GoToGlobAndWaitWithoutAltitude(GeoPoint location, IProgress <double> progress, double precisionMet, CancellationToken cancel)
        {
            await GoToGlob(location, cancel);

            progress = progress ?? new Progress <double>();
            var startLocation  = this.GlobalPosition.Value;
            var startLocation0 = startLocation.SetAltitude(0);
            var startDistance  = Math.Abs(GeoMath.Distance(location, startLocation));
            var startDistance0 = Math.Abs(GeoMath.Distance(location.SetAltitude(0), startLocation0));

            Logger.Info("GoToAndWaitWithoutAltitude {0} with precision {2:F1} m. Distance to target {3:F1}", location, precisionMet, startDistance);
            progress.Report(0);
            if (startDistance0 <= precisionMet)
            {
                Logger.Debug("Already in target, nothing to do", startLocation);
                progress.Report(1);
                return;
            }

            var sw = new Stopwatch();

            sw.Start();
            Logger.Debug("Send command GoTo to vehicle", startLocation);
            await this.GoToGlob(location, cancel).ConfigureAwait(false);

            double dist = 0;

            while (!cancel.IsCancellationRequested)
            {
                var loc  = this.GlobalPosition.Value;
                var loc0 = loc.SetAltitude(0);
                dist = Math.Abs(GeoMath.Distance(location, loc));
                var dist0 = Math.Abs(GeoMath.Distance(location.SetAltitude(0), loc0));
                var prog  = 1 - dist / startDistance;
                Logger.Trace("Distance to target {0:F1}, location: {1}, progress {2:P2}", dist, loc, prog);
                progress.Report(prog);
                if (dist0 <= precisionMet)
                {
                    break;
                }
                await Task.Delay(TimeSpan.FromSeconds(1), cancel).ConfigureAwait(false);
            }
            sw.Stop();
            Logger.Info($"Complete {sw.Elapsed:hh\\:mm\\:ss} location error {dist:F1} m");
            progress.Report(1);
        }
コード例 #6
0
        public static async Task DoRepositionAndWait(this IVehicle vehicle, GeoPoint geoPoint, double velocity, double precisionMet, int checkTimeMs, CancellationToken cancel, IProgress <double> progress)
        {
            progress = progress ?? new Progress <double>();
            var startLocation = vehicle.Rtt.RelGps.Value;
            var startDistance = GeoMath.Distance(geoPoint, startLocation);

            Logger.Info("DoRepositionAndWait {0} with V={1:F1} m/sec and precision {2:F1} m. Distance to target {3:F1}", geoPoint, velocity, precisionMet, startDistance);
            progress.Report(0);
            if (startDistance <= precisionMet)
            {
                Logger.Debug("Already in target, nothing to do", startLocation);
                progress.Report(1);
                return;
            }

            var sw = new Stopwatch();

            sw.Start();
            Logger.Debug("Send command DoReposition to vehicle", startLocation);
            await vehicle.DoReposition((float)velocity, geoPoint, cancel).ConfigureAwait(false);

            double dist = 0;

            while (!cancel.IsCancellationRequested)
            {
                var loc = vehicle.Rtt.RelGps.Value;
                dist = Math.Abs(GeoMath.Distance(geoPoint, loc));
                var prog = 1 - dist / startDistance;
                Logger.Trace("Distance to target {0:F1}, location: {1}, progress {2:P2}", dist, loc, prog);
                progress.Report(prog);
                if (dist <= precisionMet)
                {
                    break;
                }
                await Task.Delay(checkTimeMs, cancel).ConfigureAwait(false);
            }
            sw.Stop();
            Logger.Info($"Complete {sw.Elapsed:hh\\:mm\\:ss} location error {dist:F1} m");
            progress.Report(1);
        }
コード例 #7
0
 public static double DistanceTo(this GeoPoint a, GeoPoint b)
 {
     return(GeoMath.Distance(a, b));
 }
コード例 #8
0
 public static double Azimuth(this GeoPoint a, GeoPoint b)
 {
     return(GeoMath.Azimuth(a.Latitude, a.Longitude, b.Latitude, b.Longitude));
 }
コード例 #9
0
 public double AngleBetween(GeoPoint other)
 {
     return(GeoMath.Azimuth(this, other));
 }
コード例 #10
0
 public double DistanceTo(GeoPoint other)
 {
     return(GeoMath.Distance(this, other));
 }