0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【連載】LCIの使い方「エレベーター編」#10|降車・降車完了(RobotStatus)

0
Last updated at Posted at 2026-09-10

こんにちは!この記事では、 株式会社Octa Roboticsが開発・提供している ロボット・設備間連携に特化したマルチベンダー型のインターフェースサービス「LCI」 について、ロボットからの利用方法を連載形式で紹介していきます。

前回の記事では、通信プロトコルの「乗り込み、乗り込み完了(RobotStatus)」の実装を行いました。

前回 : #9 乗り込み・乗り込み完了(RobotStatus) / 次回 : #11 利用解除(Release)

今回は、「降車、降車完了(RobotStatus)」について実装を行っていきます。


おさらい

降車・降車完了(RobotStatus)のシーケンスについて、再確認していきましょう。

降車・降車完了では、それぞれ以下の手順でロボットとエレベーター(LCI)間でMQTT通信を行います。

降車・降車完了は乗り込み、乗り込み完了とほぼ同一のシーケンスです。
送信するstateの値のみ異なります。

降車

  1. ロボットからエレベーターにRobotStatus(State:5)を送信
  2. エレベーターからロボットにRobotStatusResultを送信
  3. 降車完了を送るまで、5秒間隔で実施

image.png

降車完了

  1. ロボットからエレベーターにRobotStatus(State:2)を送信
  2. エレベーターからロボットにRobotStatusResultを送信

image.png

プロトコルの仕様

前回の乗り込み・乗り込み完了で説明済みのため割愛します。

→第9回乗り込み・乗り込み完了はこちら

サンプルコードの確認

前回の乗り込み・乗り込み完了で説明済みのため割愛します。

→第9回乗り込み・乗り込み完了はこちら

サンプルコードの改良

サンプルコード(lci_client.py)では、シーケンスの降車・降車完了について以下の箇所が未実装です。

  1. ElevatorStatus内のfloor(エレベーターの現在階)とdoor(ドアの開閉情報)を確認し、降車を行ってよいか判断する
  2. 降車完了および降車中止まで5秒間隔でRobotStatus(state:5)をループする
  3. 一定時間内に乗り込みができない場合は、降車中止(state: 4)を送信する
  4. RobotStatusResult内のresultが2、3、99だった場合のエラー処理

これらの処理を行えるようにサンプルコードを改良します。

実装したコード

前回の乗り込み、乗り込み完了で作成したコードを元に関数の追加・追記を行います。

clear_robot_status_stop_event

self.stop_event_robot_statusをclearする関数です。

class LciClient
 def clear_robot_status_stop_event(self):
       self.stop_event_robot_status.clear()

do_robot_status_success_exit

do_robot_status_success_enterの一部を変更し、降車成功を送信する関数を作成します。

class LciClient
  def do_robot_status_success_exit(self, time_out: int=10):
        res = self.robot_status(RobotStatus.HAS_GOT_OFF, time_out)

        if res is not None:
            if res.result != 1:
                self.registered = False
                self.logger.error(f"Robot Status(state:2) is failed code : {res.result}")
            else:
                self.logger.info(f"Robot succeeded in exiting elevator")
        else:
            self.registered = False
            self.logger.error(f"Robot Status(state:2) code : None")
        
        return res
    

do_robot_status_cancel_exit

do_robot_status_cancel_enterの一部を変更し、self.robot_status_repeat_commandを使用して降車中止を送信する関数を作成します。

class LciClient
def do_robot_status_cancel_exit(self):
        res = self.robot_status_repeat_command(RobotStatus.CANCEL_TO_GET_OFF, 5, 5, (1,2,3,99))
        if res is not None:
            self.logger.info(f"Robot canceled to exit elevator")
        else:
            self.logger.info(f"Robot canceled to exit elevator : failed")
        self.registered = False
        return res

メイン処理(if name=='__main__':)

  1. 乗り込み完了/中止送信後に、clear_robot_status_stop_eventを実行
  2. 行き先階への登録(CallElevator)の実施
  3. wait_for_arrivalにて行き先階に到着したか、ドアが開状態であるか確認
  4. start_robot_status_open_holdを実行し、5秒間隔でドア開継続要求を実施
  5. ロボット降車(今回は20秒経過)後にstop_request_elevator_statusを実行し、エレベーター状態取得を停止
  6. end_alightingの値に応じて、降車完了か降車中止を送信
  7. 利用解除の実施

降車開始から、降車終了まで20秒かかるものとします。

main process
# Main routine
if __name__ == '__main__':
   
    ...
 
    #ロボットの乗り込みが終了した場合→True
    #ロボットの乗り込みを中止したい場合→False
    end_boarding = True
    lci_client.logger.info(f"Boarding Elevator : {end_boarding}")
    
    with lci_client.lock_robot_status:
        lci_client.stop_robot_status_open_hold()
        
        #乗り込み完了
        if end_boarding:
            res = lci_client.do_robot_status_success_enter()
            lci_client.logger.debug(res)
            time.sleep(1)

            if not res or not lci_client.is_registered:
                res = lci_client.do_release()
                lci_client.logger.debug(res)
                sys.exit(1)
        #乗り込み中止
        else:
            res = lci_client.do_robot_status_cancel_enter()
            lci_client.logger.debug(res)
            sys.exit(1)

+   time.sleep(1)
    
    #RobotStatusに関するイベントのリセット
+   lci_client.clear_robot_status_stop_event()
+   time.sleep(1)
    
    #行き先階への登録
    res = lci_client.do_call_elevator('B1', '1F')
    lci_client.logger.debug(res)
    time.sleep(1)

    #エレベーターの目的階到着・ドアの開閉状態確認
    res = lci_client.wait_for_arrival('1F', 1)

+   if res:
        #降車
+       lci_client.start_robot_status_open_hold()

        """
        ~~~ロボットのエレベーター降車~~~
        ここでロボットによるエレベーターの降車を実施します.
        今回は20秒で、ロボットが降車を行ったとみなします。
        """ 

+       roop_time = 20 + time.time()
+       while time.time() < roop_time:
+           if not lci_client.is_registered:
+               res = lci_client.do_release()
+               lci_client.logger.debug(res)
+               sys.exit(1)
+           time.sleep(1)
    
+   else:
+       res = lci_client.do_release()
+       lci_client.logger.debug(res)
+        sys.exit(1)
    
    #エレベーター状態取得終了
    lci_client.stop_request_elevator_status()
    time.sleep(1)

    #ロボットの降車が終了した場合→True
    #ロボットの降車を中止したい場合→False
+   end_alighting = True
+   lci_client.logger.info(f"Alighting Elevator : {end_alighting}")
    
+   with lci_client.lock_robot_status:
+       lci_client.stop_robot_status_open_hold()
        
        #降車完了
+       if end_alighting:
+           res = lci_client.do_robot_status_success_exit()
+           lci_client.logger.debug(res)
+           time.sleep(1)

+           if not res or not lci_client.is_registered:
+               res = lci_client.do_release()
+               lci_client.logger.debug(res)
+               sys.exit(1)
        #降車失敗
+       else:
+           res = lci_client.do_robot_status_cancel_exit()
+           lci_client.logger.debug(res)
+           sys.exit(1)
    

+   time.sleep(1)
    
    #RobotStatusに関するイベントのリセット
+   lci_client.clear_robot_status_stop_event()
+   time.sleep(1)

    #利用解除
    res = lci_client.do_release()
    lci_client.logger.debug(res)
    time.sleep(1)

動作確認

メイン処理のコードを変更し、以下の2ケースに分けて動作を確認します。

  • 20秒経過後に、do_robot_status_success_exit()を実行
    • 降車完了送信後、次のシーケンスに遷移
  • 20秒経過後に、do_robot_status_cancel_exit()を実行
    • 降車中止送信後、異常シーケンスに遷移

降車完了した場合

コード変更箇所

メイン処理のend_alightingをTrueにします。

main process
# Main routine
if __name__ == '__main__':
	
   ...
 
   #ロボットの降車が終了した場合→True
   #ロボットの降車を中止したい場合→False
+  end_alighting = True
   lci_client.logger.info(f"Alighting Elevator : {end_alighting}")
  
   with lci_client.lock_robot_status:
       lci_client.stop_robot_status_open_hold()
      
       #降車完了
       if end_alighting:
           res = lci_client.do_robot_status_success_exit()
           lci_client.logger.debug(res)
           time.sleep(1)

           if not res or not lci_client.is_registered:
               res = lci_client.do_release()
               lci_client.logger.debug(res)
               sys.exit(1)
       #降車失敗
       else:
           res = lci_client.do_robot_status_cancel_exit()
           lci_client.logger.debug(res)
           sys.exit(1)
  
   time.sleep(1)
  
   #RobotStatusに関するイベントのリセット
   lci_client.clear_robot_status_stop_event()
   time.sleep(1)

   #利用解除
   res = lci_client.do_release()
   lci_client.logger.debug(res)
   time.sleep(1)

実行結果

ログから読み取れる動作として、降車完了を送信した後、次のシーケンスである利用解除を行っています。

  • 16:44:06,050 ~ 16:44:26,885
    • 5秒間隔でドア開継続要求の実施
  • 16:44:27,137 ~ 16:44:27,309
    • 降車完了を送信
  • 16:44:30,365 ~ 16:44:30,554
    • 利用解除を送信
2026-05-27 16:44:06,049     INFO Elevator arrived
2026-05-27 16:44:06,049     INFO Door opened
2026-05-27 16:44:06,050    DEBUG Sending PUBLISH (d0, q1, r0, m30), 'b'/lci/simulator/1/1/RobotStatus/_uClosc2'', ... (64 bytes)
2026-05-27 16:44:06,217    DEBUG Received PUBLISH (d0, q1, r0, m1), '/lci/simulator/1/1/RobotStatusResult/_uClosc2', ...  (114 bytes)
2026-05-27 16:44:11,266    DEBUG Sending PUBLISH (d0, q1, r0, m33), 'b'/lci/simulator/1/1/RobotStatus/_uClosc2'', ... (65 bytes)
2026-05-27 16:44:11,426    DEBUG Received PUBLISH (d0, q1, r0, m1), '/lci/simulator/1/1/RobotStatusResult/_uClosc2', ...  (115 bytes)
2026-05-27 16:44:16,435    DEBUG Sending PUBLISH (d0, q1, r0, m36), 'b'/lci/simulator/1/1/RobotStatus/_uClosc2'', ... (65 bytes)
2026-05-27 16:44:16,577    DEBUG Received PUBLISH (d0, q1, r0, m1), '/lci/simulator/1/1/RobotStatusResult/_uClosc2', ...  (115 bytes)
2026-05-27 16:44:21,603    DEBUG Sending PUBLISH (d0, q1, r0, m40), 'b'/lci/simulator/1/1/RobotStatus/_uClosc2'', ... (65 bytes)
2026-05-27 16:44:21,724    DEBUG Received PUBLISH (d0, q1, r0, m1), '/lci/simulator/1/1/RobotStatusResult/_uClosc2', ...  (115 bytes)
2026-05-27 16:44:26,770    DEBUG Sending PUBLISH (d0, q1, r0, m43), 'b'/lci/simulator/1/1/RobotStatus/_uClosc2'', ... (64 bytes)
2026-05-27 16:44:26,885    DEBUG Received PUBLISH (d0, q1, r0, m1), '/lci/simulator/1/1/RobotStatusResult/_uClosc2', ...  (114 bytes)
2026-05-27 16:44:27,136     INFO Alighting Elevator : True
2026-05-27 16:44:27,137    DEBUG Sending PUBLISH (d0, q1, r0, m44), 'b'/lci/simulator/1/1/RobotStatus/_uClosc2'', ... (65 bytes)
2026-05-27 16:44:27,309    DEBUG Received PUBLISH (d0, q1, r0, m1), '/lci/simulator/1/1/RobotStatusResult/_uClosc2', ...  (115 bytes)
2026-05-27 16:44:27,352     INFO Robot succeeded in exiting elevator
2026-05-27 16:44:30,365    DEBUG Sending PUBLISH (d0, q1, r0, m45), 'b'/lci/simulator/1/1/Release/_uClosc2'', ... (53 bytes)
2026-05-27 16:44:30,554    DEBUG Received PUBLISH (d0, q1, r0, m1), '/lci/simulator/1/1/ReleaseResult/_uClosc2', ...  (115 bytes)

降車中止した場合

コード変更箇所

メイン処理のend_alightingをFalseにします。

main routine
# Main routine
if __name__ == '__main__':
	
   ...
 
   #ロボットの降車が終了した場合→True
   #ロボットの降車を中止したい場合→False
+  end_alighting = False
   lci_client.logger.info(f"Alighting Elevator : {end_alighting}")
  
   with lci_client.lock_robot_status:
       lci_client.stop_robot_status_open_hold()
      
       #降車完了
       if end_alighting:
           res = lci_client.do_robot_status_success_exit()
           lci_client.logger.debug(res)
           time.sleep(1)

           if not res or not lci_client.is_registered:
               res = lci_client.do_release()
               lci_client.logger.debug(res)
               sys.exit(1)
       #降車中止
       else:
           res = lci_client.do_robot_status_cancel_exit()
           lci_client.logger.debug(res)
           sys.exit(1)
  
   time.sleep(1)
  
   #RobotStatusに関するイベントのリセット
   lci_client.clear_robot_status_stop_event()
   time.sleep(1)

   #利用解除
   res = lci_client.do_release()
   lci_client.logger.debug(res)
   time.sleep(1)

実行結果

ログから読み取れる動作として、降車中止を送信した後、それ以降のシーケンスを実行していません。

  • 16:20:44,082 ~ 16:21:04,674
    • 5秒間隔でドア開継続要求
  • 16:21:05,169 ~ 16:21:05,346
    • 降車中止を送信
2026-05-27 16:20:44,082     INFO Elevator arrived
2026-05-27 16:20:44,082     INFO Door opened
2026-05-27 16:20:44,082    DEBUG Sending PUBLISH (d0, q1, r0, m31), 'b'/lci/simulator/1/1/RobotStatus/_uClosc2'', ... (65 bytes)
2026-05-27 16:20:44,181    DEBUG Received PUBLISH (d0, q1, r0, m1), '/lci/simulator/1/1/RobotStatusResult/_uClosc2', ...  (115 bytes)
2026-05-27 16:20:49,198    DEBUG Sending PUBLISH (d0, q1, r0, m34), 'b'/lci/simulator/1/1/RobotStatus/_uClosc2'', ... (65 bytes)
2026-05-27 16:20:49,302    DEBUG Received PUBLISH (d0, q1, r0, m1), '/lci/simulator/1/1/RobotStatusResult/_uClosc2', ...  (115 bytes)
2026-05-27 16:20:54,315    DEBUG Sending PUBLISH (d0, q1, r0, m37), 'b'/lci/simulator/1/1/RobotStatus/_uClosc2'', ... (65 bytes)
2026-05-27 16:20:54,406    DEBUG Received PUBLISH (d0, q1, r0, m1), '/lci/simulator/1/1/RobotStatusResult/_uClosc2', ...  (115 bytes)
2026-05-27 16:20:59,427    DEBUG Sending PUBLISH (d0, q1, r0, m41), 'b'/lci/simulator/1/1/RobotStatus/_uClosc2'', ... (65 bytes)
2026-05-27 16:20:59,529    DEBUG Received PUBLISH (d0, q1, r0, m1), '/lci/simulator/1/1/RobotStatusResult/_uClosc2', ...  (114 bytes)
2026-05-27 16:21:04,537    DEBUG Sending PUBLISH (d0, q1, r0, m44), 'b'/lci/simulator/1/1/RobotStatus/_uClosc2'', ... (65 bytes)
2026-05-27 16:21:04,674    DEBUG Received PUBLISH (d0, q1, r0, m1), '/lci/simulator/1/1/RobotStatusResult/_uClosc2', ...  (115 bytes)
2026-05-27 16:21:05,168     INFO Alighting Elevator : False
2026-05-27 16:21:05,169    DEBUG Sending PUBLISH (d0, q1, r0, m45), 'b'/lci/simulator/1/1/RobotStatus/_uClosc2'', ... (65 bytes)
2026-05-27 16:21:05,346    DEBUG Received PUBLISH (d0, q1, r0, m1), '/lci/simulator/1/1/RobotStatusResult/_uClosc2', ...  (115 bytes)
2026-05-27 16:21:05,387     INFO Robot aborted exiting the elevator

その他

サンプルコードは、以下の二つがアップロードされています。

  • lci_client.py : オリジナル
  • lci_client_tech_blog.py : 本ブログを通して改良したもの

連載記事リスト

他の記事もチェックしてみてください!


次回の記事では、通信プロトコルの「利用解除」についてサンプルコードを改良する予定です!
ご興味があれば「いいね」やフォローをいただけると励みになります!


0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?