Page 1 of 1

複数のOutputSlotから単一のInputSlotへの接続

Posted: 2017/07/25 08:36
by ooee
いつもお世話になっています。

Subjectの件、技術的に可能でしたら実装をご検討いただけないでしょうか。

Re: 複数のOutputSlotから単一のInputSlotへの接続

Posted: 2017/07/25 09:49
by caitsithware
要望ありがとうございます。

InputSlotに複数のOutputSlotを接続するとなると、どのラインの値を使用するのかが問題になりそうです。
複数接続のうちの一番新しく変更された値を使いたい、という認識で間違いないでしょうか?

また、現状での対応策として、
ParameterContainerに一時的なパラメータを作成しておき、必要に応じて格納&取り出しという方法で同様の挙動が作成できるかと思います。
もしまだお試しになってませんでしたら、一度試してみてください。

Re: 複数のOutputSlotから単一のInputSlotへの接続

Posted: 2017/07/25 13:31
by ooee
>InputSlotに複数のOutputSlotを接続するとなると、どのラインの値を使用するのかが問題になりそうです。
>複数接続のうちの一番新しく変更された値を使いたい、という認識で間違いないでしょうか?
はい、その認識で間違いありません。

>また、現状での対応策として、
>ParameterContainerに一時的なパラメータを作成しておき、必要に応じて格納&取り出しという方法で同様の挙動が作成できるかと思います。
対応策、ありがとうございます。
一度試してみます。

Re: 複数のOutputSlotから単一のInputSlotへの接続

Posted: 2017/07/27 08:54
by ooee
>ParameterContainerに一時的なパラメータを作成しておき、必要に応じて格納&取り出しという方法で同様の挙動が作成できるかと思います。
これでももちろん実現できるのですが、状態間の値のやり取りがわかりづらくなるのと、値をやり取りするのにある意味グローバルなところに
一時変数を用意する点が気になっています。(贅沢言ってすいません)

ひとつ気になったことがあるのですが、InputSlotの値が更新されたタイミング(時間)の取得は可能でしょうか?
もし可能なら、InputSlotの配列から一番新しく更新された値を取り出してOutputSlotに入れるというスクリプトを間にかませば、Subjectの内容が実現できそうだと思ったもので。

Re: 複数のOutputSlotから単一のInputSlotへの接続

Posted: 2017/07/27 11:47
by caitsithware
ooee wrote:ひとつ気になったことがあるのですが、InputSlotの値が更新されたタイミング(時間)の取得は可能でしょうか?
もし可能なら、InputSlotの配列から一番新しく更新された値を取り出してOutputSlotに入れるというスクリプトを間にかませば、Subjectの内容が実現できそうだと思ったもので。
更新タイムスタンプは現在保持していないため取得できません。
また、いまのところArborの内部処理では演算ノードの再演算のタイミング等の問題で、どの接続が最新データか選択すべきかを保証するすべがない感じです。
(内部的な問題点については最後に記述)

対処方法としては、データスロットのカスタマイズを行い、タイムスタンプ付きクラスを受け渡すことでステートからの出力タイムスタンプを得る方法があります。

まず、以下のようにスロットを定義します。

Code: Select all

[System.Serializable]
public class TimestampInt
{
    public int value;
    public float timestamp;
    
    public TimestampInt(int value)
    {
        this.value = value;
        this.timestamp = Time.time;
    }
}
 
[System.Serializable]
public class OutputSlotTimestampInt : OutputSlot<TimestampInt>
{
}
 
[System.Serializable]
public class InputSlotTimestampInt : InputSlot<TimestampInt>
{
}
そして、StateBehaviourで入出力します。

Code: Select all

public class TimestampIntBehaviour : StateBehaviour
{
	public InputSlotTimestampInt input;
	public OutputSlotTimestampInt output;

	public override void OnStateBegin()
	{
		int value = 0;
		TimestampInt data = null;
		if (input.GetValue(ref data))
		{
			Debug.LogFormat("{0} : {1}", data.value, data.timestamp);
			value = data.value;
		}
		output.SetValue(new TimestampInt(value+1));
	}
}
 
こんな感じでいかがでしょうか。

■Arbor内部的な問題点について

データスロットは演算ノードとも接続できるため、演算ノードが間に入っている場合の更新タイムスタンプは取得しようとしたタイミング(=計算されるタイミング)になってしまいます。

なぜ演算ノードがあると取得時に計算する仕様なのかは以下の通りです。
  • 出力するたびに演算ノードでの再計算は無駄が多いため、最終的に取得しようとしたときのみ演算が最適。
  • 複数のステートから演算ノードに接続して演算する場合、1つのステート側からの出力時よりも取得時のほうが準備が整っている。
  • Calculator.OnCheckDirty()がtrueを返すようになっており、常に再演算する場合もある。
このような仕様なので演算ノードが間にある場合に複数接続すると、どのラインを選択すべきかは不定になります。
例えば、こんな繋げ方とか・・・
MultiSlot.png
MultiSlot.png (88.3 KiB) Viewed 7923 times
取得しようとしたタイミングで両方の演算ノードが処理されて、結果、Input側でのタイムスタンプは同じになってしまいます。

内部的に「最初に接続されている方」と決めても良いですが、どちらが最初かぱっと見わからないので難しいですね。

ひとまず、タイムスタンプについては1つの判断基準にはなるかと思いますので、
複数接続はひとまず保留としてもタイムスタンプ自体は追加しようとかと思います。

Re: 複数のOutputSlotから単一のInputSlotへの接続

Posted: 2018/02/23 08:47
by ooee
スクリプトまで用意まで例示していただいて、ありがとうございます。
タイムスタンプ付きクラスを被せる方法で、実現したいことができそうなので試してみようと思います。