Bye Bye Moore

PoCソルジャーな零細事業主が作業メモを残すブログ

AWS LightSailにTeraTermで接続し画面転送をする

素のAWS SSHブラウザでやっても画面転送は出来ません。
TeraTermのような奴で接続してやる必要があります。

実際のところ

$ imvr foobar.png 
imvr: src/x11_window.c:106: imv_window_create: Assertion `window->x_display' failed.
Aborted (core dumped)

となり、画面転送はできない。

入れてないときは、

$ sudo apt install x11-apps

KEYは管理コンソールから確保

これをTearTerm等クライアントに登録し、画面転送オプションをセットしてやれば

chromium+selenium+RasPiで動いていたパーサーをAWS LightSailに載せ替える

shuzo-kino.hateblo.jp
のシリーズの実質的続編。

これまではseleniumで動くパーサーをRasPi4Bに載せて運用していました。
RasPi4BはARMコアなので少し環境づくりが面倒だったこと、それ以上にずっと繋いでないと動かない仕様もどうかと思い、載せ替えを検討。
Wordpresを構築する際に活用したAWS LightSailを使う事にしました。

実際のところ

環境

手順

前準備

例のごとくaptを最新に。
どこかのアホのように横着するとchromium-browserが見つからないとか言われ無駄な時間を過ごす事になります。

$ sudo apt update
$ sudo apt upgrade

AWS LightSailで入るUbuntu20LTSに入ってないパッケージ群を先に導入。
chromiumdriverを動作させるのに必要なlibss3*1と、解凍用のzipコマンド。

$ sudo apt install libss3-dev zip
pipの導入

デフォではpipが入っていないので導入。
aptだとpip自体の更新が上手くいかないという情報も出てますが……一旦動かすだけなのでね……。

$ sudo apt install pip
seleniumを導入

はい、本チャンのseleniumです。
pipが入っているので楽々。

$ pip install selenium
chromium-browserとchromedriver

続いてchromium本体と、chromedriverを導入。

$ sudo apt install chromium-browser 
$ apt install libnss3-dev 

以下のChromium公式サイトから、入れたChromiumにあったchromiumdriverを導入
執筆時点で導入できたバージョンは93.0.4577.63 なので、chromedriverもこれに合わせるように。
ChromeDriver - WebDriver for Chrome - Downloads
わたしの場合は以下のような感じに。

$ wget https://chromedriver.storage.googleapis.com/93.0.4577.63/chromedriver_linux64.zip
$ unzip chromedriver_linux64.zip

解凍が終わったchromedriverを実行パスが届いてるトコに移動。
元のzipファイルは混乱を避ける意味でも消しておく。

$ sudo mv chromedriver /usr/local/bin
$ rm chromedriver*

これで環境導入は完了。
次はスクリプトを。

スクリプトを書く

ログイン=> ページ内のテーブルから要素を引っ張り出して標準出力に吐くという基本は前回と同じ動き。
せっかくなので、BeautifulSoupで内部でパースするように書き換え。
リモートデバッグ扱いになるのは前と同じなので、当該オプションを忘れぬよう*2

# -*- coding: utf-8 -*-

import time
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from bs4 import BeautifulSoup

CHROME_BIN   = '/usr/bin/chromium-browser'
CHROMEDRIVER = '/usr/local/bin/chromedriver'

# LogIn Info

USER_ID   = '###'
USER_PASS = '###'


# TargetURL

LOGINPAGE = '###'
TOPPAGE   = '###'


def get_driver():
    options = Options()
    options.binary_location = CHROME_BIN
    options.add_argument("--remote-debugging-port=9222")
    options.add_argument('--headless')
    return webdriver.Chrome(CHROMEDRIVER, options=options)

if __name__ == '__main__':

    print("start...\r\n")
    driver = get_driver()

    # URL
    print("Connect URL...\r\n")
    driver.get(LOGINPAGE)


    # ID/PAS
    print("Enter ID/PASS\r\n")
    id = driver.find_element_by_name("lid")
    id.send_keys(USER_ID)
    password = driver.find_element_by_name("lpd")
    password.send_keys(USER_PASS)

    # login
    print("Click Button\r\n")
    login_button = driver.find_element_by_class_name('btn-entry')
    login_button.click()

    # nextbutton
    print("NextPage....\r\n")
    driver.get(TOPPAGE)
    html = driver.page_source
    soup = BeautifulSoup(html, 'html.parser')

    for items in soup.select('tbody tr'):
      data = [item.text for item in items.select('td.device-data')]
      print(data)

    driver.quit()

*1:これは、セキュリティを考慮したクライアント・サーバアプリケーションのクロス プラットフォームな開発の補助を目的としたライブラリ群です。SSLv2 および v4, TLS, PKCS #5, #7, #11, #12, S/MIME, X.509 v3 証明書や、その他のセキュリティ 標準に対応しています。 https://packages.debian.org/ja/sid/libnss3 より

*2:私は忘れて30分ほど無駄にしました

xArmにROS環境をつくる その3:rospy経由でpythonから動かす

PythonでROSメッセージをおくる方法として、rospyの活用があります

実際のところ

まず使うためのサービス名を把握

$ rosservice list
/rosout/get_loggers
/rosout/set_logger_level
・・・
/xarm/vacuum_gripper_set
/xarm/velo_move_joint
/xarm/velo_move_line
/xarm/xarm_driver/get_loggers
/xarm/xarm_driver/set_logger_level

目当てのサービス名move_jointで使っているメッセージを把握

$ rosservice type /xarm/move_joint
xarm_msgs/Move

そのメッセージの中身を確認

$ rossrv show xarm_msgs/Move
float32[] pose
float32 mvvelo
float32 mvacc
float32 mvtime
float32 mvradii
---
int16 ret
string message

rospyを使ってみる

先ほど確認したメッセージをrospy経由で送付
ROSのディレクトリが環境変数に突っ込まれていれば、メッセージはパスを特にしていせず動かせる

#!/usr/bin/env python
import rospy
from xarm_msgs.srv import Move

rospy.wait_for_service('/xarm/move_joint')
response = rospy.ServiceProxy('/xarm/move_joint', Move)

res = response( [0,   0,   0,0,0,0], 0.35, 7, 0, 0 )
res = response( [0.1, 0,   0,0,0,0], 0.35, 7, 0, 0 )
res = response( [0.1, 0.1, 0,0,0,0], 0.35, 7, 0, 0 )
res = response( [0,   0,   0,0,0,0], 0.35, 7, 0, 0 )

print(res)

ちょっと改良

以上ではメンテ性が悪すぎるのでパラメータをバラします

#!/usr/bin/env python

import rospy
from xarm_msgs.srv import Move

rospy.wait_for_service('/xarm/move_joint')

payload = Move
payload.pose     = [0.0,0,0,0,0,0]
payload.mvvelo   = 0.35
payload.mvacc    = 7
payload.mvtime   = 0
payload.mvradii  = 0

response = rospy.ServiceProxy('/xarm/move_joint', Move)

res = response(payload.pose, payload.mvvelo, payload.mvacc, payload.mvtime, payload.mvradii)


payload.pose = [0.1, 0, 0,0,0,0]
res = response(payload.pose, payload.mvvelo, payload.mvacc, payload.mvtime, payload.mvradii)

payload.pose[1] = 0.1
res = response(payload.pose, payload.mvvelo, payload.mvacc, payload.mvtime, payload.mvradii)

print(res)

AirPlayでmacOSとiPad/iPhoneが繋がらなくなったら再起動してみるのも手

AirPlayを使うと、macOSiPad/iPhoneの画面拡張が出来たりして便利です。
ペッパー君的な端末をipad 、操縦機をmacbookにして何かあったら画面に介入したりとか。

で、会社で動いていたネットワーク構成を展示会に持っていったらなぜか起動しなくなったケースが。

そもそものデバイスが相互に確認できない状況。
経験上、もしやと思い再起動したら無事認識してくれました。
横着して設定持ち越すより、セットアップを前提に考えないとダメですね。

xArmにROS環境をつくる その2:サービスを経由してxArmを動かす

実際のところ

roslaunch

$ YOURIP=192.168.1.230
$ roslaunch xarm_bringup xarm7_server.launch robot_ip:=$YOURIP

操作側端末の準備

サービス経由でロボットを動かす

$ rosservice call /xarm/motion_ctrl 8 1
ret: 0
message: "motion enable, ret = 0"

モードの切り替え

$ rosservice call /xarm/set_mode 0
ret: 0
message: "pose mode, ret = 0"

待機状態を切替

$ rosservice call /xarm/set_state 0
ret: 0
message: "start, ret = 0"

軸を最低限動かす

$ rosservice call /xarm/move_joint [0.1,0,0,0,0,0,0] 0.35 7 0 0

スクリプトを動かす

$ cat test.bash
#!/bin/bash

rosservice call /xarm/motion_ctrl 8 1
rosservice call /xarm/set_mode 0
rosservice call /xarm/set_state 0

#まずHome
rosservice call /xarm/go_home [] 0.35 7 0 0

#Z X Yの順にうごかす……ただし、スペースは開けないこと
rosservice call /xarm/move_line_tool  [0,0,-50,0,0,0] 200 2000 0 0
rosservice call /xarm/move_line_tool  [50,0,0,0,0,0] 200 2000 0 0
rosservice call /xarm/move_line_tool  [0,50,0,0,0,0] 200 2000 0 0

rosservice call /xarm/go_home [] 0.35 7 0 0

move_line_toolは相対位置で動くので、行き過ぎないように注意