gpt4 book ai didi

c# - 组合依赖于其他可观察量的可观察量

转载 作者:太空宇宙 更新时间:2023-11-03 19:41:35 24 4
gpt4 key购买 nike

我正在使用高度可观测值模拟无人机的飞行。高度应根据此方案变化:

  1. 高度从 0 增加到 BaseAltitude,即固定高度。
  2. 达到 BaseAltitude 后,无人机开始巡航,描述正弦波,从 BaseAltitude 开始
  3. 收到信号后,无人机应开始着陆。也就是说,从当前高度开始,无人机应该直线下降直到达到 0

您可能会注意到,当着陆开始时,高度在设计时是未知的。起飞顺序应以最后一个高度为起点。因此,一个序列取决于另一个序列产生的最后一个值。我脑袋疼!

好吧,我完全坚持这一点。

我目前唯一的代码如下。我把它用来说明问题。你会很快得到它...

public class Drone
{
public Drone()
{
var interval = TimeSpan.FromMilliseconds(200);

var takeOff = Observable.Interval(interval).TakeWhile(h => h < BaseAltitude).Select(t => (double)t);

var cruise = Observable
.Interval(interval).Select(t => 100 * Math.Sin(t * 2 * Math.PI / 180) + BaseAltitude)
.TakeUntil(_ => IsLanding);

var landing = Observable
.Interval(interval).Select(t => ??? );

Altitude = takeOff.Concat(cruise).Concat(landing);
}

public bool IsLanding { get; set; }
public double BaseAltitude { get; set; } = 100;
public IObservable<double> Altitude { get; }
}

最佳答案

您真的应该尝试制作可观察对象,以便它模拟选择起飞或降落随时 - 就像无人机用户可能做的那样。

如果您像这样编写代码,那将变得非常简单:

public class Drone
{
public Drone()
{
this.Altitude = ...
}

private bool _isLanding = true;
private Subject<bool> _isLandings = new Subject<bool>();

public bool IsLanding
{
get => _isLanding;
set
{
_isLanding = value;
_isLandings.OnNext(value);
}
}

public double BaseAltitude { get; set; } = 100.0;
public IObservable<double> Altitude { get; }
}

每次 IsLanding 更改时,私有(private) _isLandings 都会触发一个可用于更改无人机模式的值。

现在,Altitude 的定义从这个基本模式开始:

    this.Altitude =
_isLandings
.Select(x => x ? landing : takeOff.Concat(cruise))
.Switch()
.StartWith(altitude);

这里使用 .Switch() 是关键。每当 _isLandings 产生一个值时,开关就会在着陆或起飞之间进行选择。它成为响应上升或下降的单一可观察对象。

完整代码如下:

public class Drone
{
public Drone()
{
var altitude = 0.0;
var interval = TimeSpan.FromMilliseconds(200);

IObservable<double> landing =
Observable
.Interval(interval)
.TakeWhile(h => altitude > 0.0)
.Select(t =>
{
altitude -= 10.0;
altitude = altitude > 0.0 ? altitude : 0.0;
return altitude;
});

IObservable<double> takeOff =
Observable
.Interval(interval)
.TakeWhile(h => altitude < BaseAltitude)
.Select(t =>
{
altitude += 10.0;
altitude = altitude < BaseAltitude ? altitude : BaseAltitude;
return altitude;
});

IObservable<double> cruise =
Observable
.Interval(interval)
.Select(t =>
{
altitude = 10.0 * Math.Sin(t * 2.0 * Math.PI / 180.0) + BaseAltitude;
return altitude;
});

this.Altitude =
_isLandings
.Select(x => x ? landing : takeOff.Concat(cruise))
.Switch()
.StartWith(altitude);
}

private bool _isLanding = true;
private Subject<bool> _isLandings = new Subject<bool>();

public bool IsLanding
{
get => _isLanding;
set
{
_isLanding = value;
_isLandings.OnNext(value);
}
}

public double BaseAltitude { get; set; } = 100.0;
public IObservable<double> Altitude { get; }
}

你可以用这个来测试它:

var drone = new Drone();

drone.Altitude.Subscribe(x => Console.WriteLine(x));

Thread.Sleep(2000);

drone.IsLanding = false;

Thread.Sleep(4000);

drone.IsLanding = true;

关于c# - 组合依赖于其他可观察量的可观察量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52535917/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com