Dummy MPS(MEMO)

まずは,RefBox と MPS の通信について見てみましょう.

llsf-refbox/cfg/config.yaml によりますと,

  sps:
    enable: false
    host: !ipv4 192.168.1.77
    port: !tcp-port 502
    test-lights: true

  mps:
    enable: false
    # type: 1(incoming station), 2(singel p&p), 3(double p&p), 4(delivery station)
    stations:
      C-BS:
        active: false
        type: BS
        host: !ipv4 192.168.2.27
        port: !tcp-port 502

となっています.

まず,sps ってなんじゃらホイって感じですが,llsf-refbox/src/libs/llsf_sps/sps_comm.cpp を見ると,

 * The SPS controls the signal lights and reads and writes from and
 * to the RFID sensors. This class encapsulates the communication via
 * Modbus and provides access to LLSF-specific actions.

とあり,Logistics League sponsored by FESTO (LLSF) の頃の,パックをシグナルに運んでいた時代のシグナル側に搭載していた制御器っぽいです.
その当時は,パックにRF-ID タグを取り付け,タグリーダー/ライターを使って,状態をパックに書き込んでいました.
それが,今はMPSに変わりましたが,その時の設定が1つだけ残っているようです.
というわけで,この部分(IP:192.168.1.77)の装置は,無視できそうです.
ただ,SPS という単語は今後も出てきましたので,こちらは無視できなさそうです.

RCLL で重要なのは,MPS です.
こちらは,192.168.2.0/24 のネットワークを構築しているようです.
ロボットなどの試合用ネットワークは172.26.0.0/16 ですので,1つのLAN ケーブル上に2つのネットが存在することになります.
192.168.2.0 は,DHCP を使うよりは,手動割り当ての方が無難そうです.
(DHCP を利用すると,チームのAPのDHCP サーバにつながる危険性があるからです).

port として502 を指定しています.
SPS だけでなく,MPS にもある設定ですので,SPS の頃と同じ通信制御方式を使っているっぽいようです.
502 で検索してみると,modbus (モドバス)が出てきました.
そういえば,インストール時にそんな名前のパッケージを入れたような….

RefBox 周りの通信はProtoBuf ですが,このmodbus は今も使っているのか,それとも過去の設定が残っているのか?
RefBox からMPS への通信を調べてみましょう.

まずは,頭脳的なCLIPS から見てみましょう.
llsf-refbox/src/games/rcll の exploration.clp 辺りから手を出してみます.

探索フェーズでMPS と通信をするのは,各チームからマシンの情報をRefBox へ送った時に,それが合っているか否かをLED の点灯パターンを変更するときです.
defrule exploration-report-zone-correct と,defrule exploration-report-zone-wrong の部分です.

正しい報告の時は,緑ランプがつき,間違った報告の時は赤ランプが点滅します.

(modify ?mf (desired-lights GREEN-ON))
...
(modify ?mf (desired-lights RED-BLINK))

上記の部分ですね.
そうすると,desired-lights が怪しいです.

grep してみると,いろいろなclp から呼び出していますが,それを利用しているのは,machines.clp のmachine-lights です.

(defrule machine-lights "Set machines if desired lights differ from actual lights"
  ?mf <- (machine (name ?m) (actual-lights $?al) (desired-lights $?dl&:(neq ?al ?dl)))
  =>
  ;(printout t ?m " actual lights: " ?al "  desired: " ?dl crlf)
  (modify ?mf (actual-lights ?dl))
        (if (member$ RED-ON ?dl) then (bind ?red-state ON)
         else (if (member$ RED-BLINK ?dl) then (bind ?red-state BLINK)
         else (bind ?red-state OFF)))
        (if (member$ YELLOW-ON ?dl) then (bind ?yellow-state ON)
         else (if (member$ YELLOW-BLINK ?dl) then (bind ?yellow-state BLINK)
         else (bind ?yellow-state OFF)))
        (if (member$ GREEN-ON ?dl) then (bind ?green-state ON)
         else (if (member$ GREEN-BLINK ?dl) then (bind ?green-state BLINK)
         else (bind ?green-state OFF)))

        (mps-set-lights (str-cat ?m) (str-cat ?red-state) (str-cat ?yellow-state) (str-cat ?green-state))
)

実際の点灯パターンと,変数が保持しているパターンとが異なるのを見つけたら,MPS に保持しているパターンを送るルールです.

とすると,実際に通信しているのは,mps-set-lights の部分と考えられます.

ところが,mps-set-lights でgrep してみても,simulation.clp しかひっかかりません.

(deffunction mps-set-lights (?name ?state-red ?state-yellow ?state-green)
  (bind ?name (sym-cat ?name))
  ;(printout t "Simulated light setting for " ?name ": red=" ?state-red
        ;                                       " yellow=" ?state-yellow "  green=" ?state-green crlf)
)

simulation.clp という名前から嫌な予感がしますが,何も動作させないルールの様に見えます.

実は,実機につながらない時(config.yaml にて,mps/enable: false となっている時)の,ダミーのルールとなっています.
つながる時(mps/enable: true)は,llsf-refbox/src/refbox/refbox.cpp の LLSFRefBox::setup_clips() にて,

    clips_->add_function("mps-set-lights", sigc::slot<void, std::string, std::string, std::string, std::string>(sigc::mem_fun(*this, &LLSFRefBox::clips_mps_set_lights)));

mps-set-lights に対して,LLSFRefBox::clips_mps_set_lights 関数を割り当てていますね.

void
LLSFRefBox::clips_mps_set_lights(std::string machine, std::string red_state,
                                 std::string yellow_state, std::string green_state)
{
...
  if (! mps_)  return;
  MPS *station;
  station = mps_->get_station(machine, station);
...
    station->setAllLights(lights);
...
}

という感じで,mps_ が存在したら get_station で machine 名に一致するMPS を取ってきて,setAllLights(lights) で,シグナルの点灯パターンを与えています.

setAllLights は,llsf-refbox/src/libs/llsf_sps/mps.cpp にあります.

void
MPS::setAllLights(int lights[3]) {
  uint16_t send[3] = {(uint16_t) lights[0], (uint16_t) lights[1], (uint16_t) lights[2]};

  int rc = modbus_write_registers(mb, 3, 3, send);

  if(rc == -1) {
    machineState = DISCONNECTED;
  }
}

ようやく,辿り着きました.
modbus_write_registers(mb, 3, 3, send) で,MPS にデータを送っています.

これが,RefBox からMPS にデータを送っているところです.
(機器のレジスターに書き込んでいる感じですね).

ここを中心に,ダミーMPS を検討しましょう.

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

*