Ubuntu16.04にROS kineticインストールとD435iでSLAMのサンプル動作まで
自分の作業メモです
リアルセンスのドライバアップデート
書き込みexeをダウンロードするために下記リンクに行き、左枠にあるダウンロードをクリック
Download Windows* Device Firmware Update Tool for Intel® RealSense™ D400 Product Family
次にファームウェアの最新をダウンロードしてくる
Downloads for Intel® RealSense™ Depth Camera D435i
1, D435iを接続する
2, ダウンロードした両方のファイルを解凍し、同じフォルダに入れる
3, intel-realsense-dfu.exeを起動
4, [2][Enter]を押して現在の接続されたカメラとFWバージョンを確認(4だとすべてのカメラを確認できる)
5, [1][Enter]を押して書き込みモードにする
6, 再度[1]を押す
7, 相対パスの[.\Signed_Image_UVC_5_12_3_0.bin]を記入(適宜バージョン書き換え)
8, 書き込みが終わると何かキーを押せと言われるので何か押す
9, [2][Enter]を押して現在の接続されたカメラとFWバージョンを確認(4だとすべてのカメラを確認できる)
バージョンが書き換わったことを確認して終わり
リアルセンスインストール
自分のカーネルバージョンを確認する
2020/4/29現在
Ubuntu LTSカーネル4.4、4.8、4.10、4.13、4.15、4.18 * 5.0 *および5.3 *をサポートしています。
uname -r
サポート対象かを確認する
パッケージのインストール
サーバーの公開鍵を登録
sudo apt-key adv --keyserver keys.gnupg.net --recv-key F6E65AC044F831AC80A06380C8B3A55A6F3EFCDE || sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-key F6E65AC044F831AC80A06380C8B3A55A6F3EFCDE
リストに追加
sudo add-apt-repository "deb http://realsense-hw-public.s3.amazonaws.com/Debian/apt-repo xenial main" -u
もし「AppStream cache update completed, but some metadata was ignored due to errors.」が出たら
ここを参考にする
Ubuntu 16.04 LTSの“AppStream cache update completed, but some metadata was ignored due to errors.”を直す : りんご便り
ライブラリンストール
sudo apt-get install librealsense2-dkms=1.3.1-0ubuntu3 sudo apt install librealsense2-utils
ROS kineticインストール
(一応上から入れていけばリアルセンスが動作することを確認してますが、本当はリアルセンスのライブラリを最初に入れないといけないかも?)
まずsources.listを設定
sudo sh -c 'echo "deb http://packages.ros.org/ros/ubuntu $(lsb_release -sc) main" > /etc/apt/sources.list.d/ros-latest.list'
つぎにキー設定
sudo apt-key adv --keyserver 'hkp://keyserver.ubuntu.com:80' --recv-key C1CF6E31E6BADE8868B172B4F42ED6FBAB17C654
アップデートして最新に
sudo apt-get update
とりあえずrosのパッケージがインストール可能か見てみる
apt-cache search ros-kinetic
デスクトップフルインストール:(推奨):
(ROS、rqt、rviz、ロボット汎用ライブラリ、2D / 3Dシミュレータ、ナビゲーション、2D / 3D知覚)
sudo apt-get install ros-kinetic-desktop-full
fullじゃなくてもいいならこちら
(デスクトップインストール: ROS、rqt、rviz、およびロボット汎用ライブラリ
sudo apt-get install ros-kinetic-desktop
)
ROS初期化
sudo rosdep init rosdep update
環境設定
echo "source /opt/ros/kinetic/setup.bash" >> ~/.bashrc source ~/.bashrc
パッケージをビルドするための依存関係
sudo apt install python-rosdep python-rosinstall python-rosinstall-generator python-wstool build-essential
roscore
で実行できたらok
リアルセンスでSLAMする準備
sudo apt-get install ros-kinetic-realsense2-camera
imu_filter_madgwick:
sudo apt install ros-kinetic-imu-filter-madgwick
rtabmap_ros:
sudo apt install ros-kinetic-rtabmap-ros
robot_localization:
sudo apt install ros-kinetic-robot-localization
D435iを接続して起動確認
roslaunch realsense2_camera opensource_tracking.launch
画面が起動して表示開始するか確認
「参考」
SLAM with D435i · IntelRealSense/realsense-ros Wiki · GitHub
pythonで起動させたスレッドを殺す
pythonでサブプロセスから起動させた子を停止させて殺します。
色々調べた結果、呼んだ時のIDを指定して止めることにしました。
プログラム
[thread_test.py]
# -*- coding:utf8 -*- import time import subprocess from subprocess import Popen import os import signal cmd = "python thread_test_child.py" proc = subprocess.Popen("exec " + cmd, stdout=subprocess.PIPE, shell=True) print( "process id = %s" % proc.pid ) print(proc.stdout.readline()) os.killpg(os.getpgid(proc.pid), signal.SIGTERM)
呼び出す子プロセス
[thread_test_child.py]
print("====")
↓結果↓
process id = 22818 b'====\n' Terminated
終わり
raspberrypi3のbluetoothライブラリを最新にする
(2019/3/1時点での記事です)
ラスベリーパイ3でbluetoothの通信をしている時にちょっと不具合等が起きたので、最新のライブラリに更新しました。
使っているのはblueZになります。
環境
Raspberrypi3B raspbian 4.14.79-v7+
解凍からインストールまで
tar xvf bluez-5.50.tar.xz cd bluez-5.50 sudo apt update sudo apt install -y libusb-dev libdbus-1-dev libglib2.0-dev libudev-dev libical-dev libreadline-dev ./configure --prefix=/usr --mandir=/usr/share/man --sysconfdir=/etc --localstatedir=/var --enable-experimental --enable-midi make sudo make install sudo reboot sudo cp /usr/libexec/bluetooth/bluetoothd /usr/lib/bluetooth bluetoothctl -v bluetoothd --version
下2つのコマンドを打つと5.50のバージョンが出てくると思います。
終わり
pythonでスレッドを再起動させる
pythonでマルチスレッドを使っている時にスレッドがエラーで停止したときに再起動させて復活させる。
環境
python 3.5.2
プログラム
サブスレッドで÷0をして意図的にエラーをして、それをメインが監視して落ちていたら再起動
ここでは監視としてメインとスレッドの時間を比較して監視する
import threading, time global_lock = threading.Lock() # LOCK OBJECT global_time = 0 class sub_while(threading.Thread): def __init__(self): threading.Thread.__init__(self) def run(self): global global_time time_cnt=0 while True: global_lock.acquire() time_cnt = time_cnt+1 global_time = int(time.time()) global_lock.release() print("sub_thread:",int(time.time())) if(time_cnt >= 5): #error val = 100/0 time.sleep(1) if __name__ == "__main__": global global_time thread1 = sub_while() thread1.start() #再起動閾値時間 threshold_time =5 while True: print("main_time:",int(time.time())) print("diff_time:",int(time.time()) - global_time) global_lock.acquire() #スレッド監視 if(int(time.time()) - global_time > threshold_time): print("-- thread restart --") thread1 = sub_while() thread1.start() global_lock.release() time.sleep(1)
結果
sub_thread: 1543545253 main_time: 1543545253 diff_time: 0 main_time: 1543545254 sub_thread: 1543545254 diff_time: 0 main_time: 1543545255 sub_thread: 1543545255 diff_time: 0 main_time: 1543545256 sub_thread: 1543545256 diff_time: 0 main_time: 1543545257 diff_time: 0 sub_thread: 1543545257 Exception in thread Thread-1: Traceback (most recent call last): File "/usr/lib/python3.5/threading.py", line 914, in _bootstrap_inner self.run() File "threadtest2.py", line 27, in run val = 100/0 ZeroDivisionError: division by zero main_time: 1543545258 diff_time: 1 main_time: 1543545259 diff_time: 2 main_time: 1543545260 diff_time: 3 main_time: 1543545261 diff_time: 4 main_time: 1543545262 diff_time: 5 main_time: 1543545263 diff_time: 6 -- thread restart -- sub_thread: 1543545263 main_time: 1543545264 diff_time: 0 sub_thread: 1543545264 main_time: 1543545265 diff_time: 1 sub_thread: 1543545265 main_time: 1543545266 diff_time: 1 sub_thread: 1543545266 main_time: 1543545267 diff_time: 1 sub_thread: 1543545267 Exception in thread Thread-2: Traceback (most recent call last): File "/usr/lib/python3.5/threading.py", line 914, in _bootstrap_inner self.run() File "threadtest2.py", line 27, in run val = 100/0 ZeroDivisionError: division by zero main_time: 1543545268 diff_time: 1 main_time: 1543545269 diff_time: 2
以上。
ubuntuでpythonのbluetooth開発環境を構築3
bluepyでプログラムを作っていましたがDelegateやNotificationの部分できちんと動作しなかったところがあるので、またライブラリを変更します
今回使ったのはこちら
github.com
環境
ubuntu16.04
python2.7
RaspberryPi3 B+ でも確認
(Linux raspberrypi.local 4.14.71-v7+ #1145 SMP Fri Sep 21 15:38:35 BST 2018 armv7l GNU/Linux)(STRETCH)
pythonは2系で動かします
Adafruit_Python_BluefruitLEインストール
sudo apt-get update sudo apt-get -y install libusb-dev libdbus-1-dev libglib2.0-dev libudev-dev libical-dev libreadline-dev git clone https://github.com/adafruit/Adafruit_Python_BluefruitLE cd Adafruit_Python_BluefruitLE/ sudo python2 setup.py install
ここまでは公式通りにインストール
しかし、ここからbluez-5.33を公式通りにインストールしたらエラーが出たため5.37を入れます
cd ~ wget http://www.kernel.org/pub/linux/bluetooth/bluez-5.37.tar.xz tar xvf bluez-5.37.tar.xz cd bluez-5.37 ./configure make sudo make install sudo systemctl start bluetooth sudo systemctl enable bluetooth
lowEnergy有効化
sudo nano /lib/systemd/system/bluetooth.service 9行目を ExecStart=/usr/local/libexec/bluetooth/bluetoothd から ExecStart=/usr/local/libexec/bluetooth/bluetoothd --experimental に修正
sudo systemctl daemon-reload sudo systemctl restart bluetooth
そしたらサンプルプログラムを動かします。
手持ちが前回同様blenano2なのでそれを使いました。
(プログラムはこちら)
blenano2は電源入れておいて、
examples/low_level.pyを編集します
# Example of low level interaction with a BLE UART device that has an RX and TX # characteristic for receiving and sending data. This doesn't use any service # implementation and instead just manipulates the services and characteristics # on a device. See the uart_service.py example for a simpler UART service # example that uses a high level service implementation. # Author: Tony DiCola import logging import time import uuid import struct import binascii import Adafruit_BluefruitLE # Enable debug output. #logging.basicConfig(level=logging.DEBUG) # Define service and characteristic UUIDs used by the UART service. UART_SERVICE_UUID = uuid.UUID('713d0000-503e-4c75-ba94-3148f18d941e') #TX_CHAR_UUID = uuid.UUID('6E400002-B5A3-F393-E0A9-E50E24DCCA9E') RX_CHAR_UUID = uuid.UUID('713d0001-503e-4c75-ba94-3148f18d941e') # Get the BLE provider for the current platform. ble = Adafruit_BluefruitLE.get_provider() # Main function implements the program logic so it can run in a background # thread. Most platforms require the main thread to handle GUI events and other # asyncronous events like BLE actions. All of the threading logic is taken care # of automatically though and you just need to provide a main function that uses # the BLE provider. def main(): # Clear any cached data because both bluez and CoreBluetooth have issues with # caching data and it going stale. ble.clear_cached_data() # Get the first available BLE network adapter and make sure it's powered on. adapter = ble.get_default_adapter() adapter.power_on() print('Using adapter: {0}'.format(adapter.name)) # Disconnect any currently connected UART devices. Good for cleaning up and # starting from a fresh state. print('Disconnecting any connected UART devices...') ble.disconnect_devices([UART_SERVICE_UUID]) # Scan for UART devices. print('Searching for UART device...') try: adapter.start_scan() # Search for the first UART device found (will time out after 60 seconds # but you can specify an optional timeout_sec parameter to change it). device = ble.find_device(service_uuids=[UART_SERVICE_UUID]) if device is None: raise RuntimeError('Failed to find UART device!') finally: # Make sure scanning is stopped before exiting. adapter.stop_scan() print('Connecting to device...') device.connect() # Will time out after 60 seconds, specify timeout_sec parameter # to change the timeout. # Once connected do everything else in a try/finally to make sure the device # is disconnected when done. try: # Wait for service discovery to complete for at least the specified # service and characteristic UUID lists. Will time out after 60 seconds # (specify timeout_sec parameter to override). print('Discovering services...') device.discover([UART_SERVICE_UUID], [ RX_CHAR_UUID])#TX_CHAR_UUID # Find the UART service and its characteristics. uart = device.find_service(UART_SERVICE_UUID) rx = uart.find_characteristic(RX_CHAR_UUID) #tx = uart.find_characteristic(TX_CHAR_UUID) # Write a string to the TX characteristic. #print('Sending message to device...') #tx.write_value('Hello world!\r\n') # Function to receive RX characteristic changes. Note that this will # be called on a different thread so be careful to make sure state that # the function changes is thread safe. Use queue or other thread-safe # primitives to send data to other threads. def received(data): #print('Received: {0}'.format((data))) print(binascii.b2a_hex(data)) # Turn on notification of RX characteristics using the callback above. print('Subscribing to RX characteristic changes...') rx.start_notify(received) # Now just wait for 30 seconds to receive data. print('Waiting 60 seconds to receive data from the device...') time.sleep(60) finally: # Make sure device is disconnected on exit. device.disconnect() # Initialize the BLE system. MUST be called before other BLE calls! ble.initialize() # Start the mainloop to process BLE events, and run the provided function in # a background thread. When the provided main function stops running, returns # an integer status code, or throws an error the program will exit. ble.run_mainloop_with(main)
python2で実行すると
Using adapter: astina-System-Product-Name Disconnecting any connected UART devices... Searching for UART device... Connecting to device... Discovering services... Subscribing to RX characteristic changes... Waiting 60 seconds to receive data from the device... 0102030000 0102030000 0102030000
みたいな感じでbluetooth経由で受信したデータが表示されます。(表示した受信データはblenano2のプログラムをちょっといじったので違います)
ちなみにDiscovering services...で止まってしまう場合は内部のbluetooth設定とかで止まっている可能性があります。
その場合は手動でbluetoothをオンオフしたりPCを再起動させたほうがいいです。
またRaspberryPi3 B+でも確認できました。
以上です。
ubuntu16でpythonのbluetooth開発環境を構築2
前回やったのはその後エラーで大変だったので、ちょっとやり直し。
環境
ubuntu16.04
python3.5.2
bluepyインストール
bluepy · PyPI
↑まず、ここからダウンロードしておく
2018/10/26現在最新は1.2.0
cd sudo apt-get install libglib2.0-dev tar -xzvf IanHarvey-bluepy-v-1.1.4-0-g117ac3d.tar.gz cd IanHarvey-bluepy-117ac3d/ sudo python3 setup.py build sudo python3 setup.py install
・インストール成功しているか確認
cd IanHarvey-bluepy-v-1.1.4-0-g117ac3d/bluepy python scanner.py Traceback (most recent call last): File "scanner.py", line 18, in <module> scanner.scan(10.0, passive=True) File "/usr/local/lib/python3.5/dist-packages/bluepy-1.1.4-py3.5.egg/bluepy/btle.py", line 679, in scan self.start(passive=passive) File "/usr/local/lib/python3.5/dist-packages/bluepy-1.1.4-py3.5.egg/bluepy/btle.py", line 617, in start self._mgmtCmd("le on") File "/usr/local/lib/python3.5/dist-packages/bluepy-1.1.4-py3.5.egg/bluepy/btle.py", line 276, in _mgmtCmd "Failed to execute mgmt cmd '%s'" % (cmd)) bluepy.btle.BTLEException: Failed to execute mgmt cmd 'le on'
エラーが出る(今になって思うとこの時bluetoothドングル挿してなかったかも...)
また、2行目のfrom __future__ import print_functionは消しておく
・bluetoothの確認
(ドングルさして確認)
sudo /usr/local/bin/blescan -i=0 Scanning for devices... Device (new): **:**:**:**:**:** (random), -62 dBm (not connectable) Complete 16b Services: <****> 16b Service Data: <****0000000000000000000000000000000000000000> Manufacturer: <***********>
確認できた
・権限付与
また、調べてるとbluepy-helperでエラーが出てる人が多かったのでこちらも対処
sudo setcap 'cap_net_raw,cap_net_admin+eip' bluepy-helper
・bluepyが使えるか確認
python scanner.py Scanning for devices... Device (new): d2:18:5c:a9:20:33 (random), -43 dBm Flags: <06> Complete Local Name: 'MyBlePeripheral' Complete 128b Services: <1e948df1483194ba754c3e5000003d71>
ちなみに見つかったのはredbearのblenano2(プログラムはこちら)