読者です 読者をやめる 読者になる 読者になる

Yura YuLife

ITエンジニアの覚え書き

BitBucket で Git LFS の転送に失敗する場合の対処法

動作環境

Git LFS でサイズの大きいファイルの転送に失敗する場合

Git LFS を用いて BitBucket にサイズの大きいファイルを push する場合、 timeout エラーが発生して失敗することがあります。

特に HTTPS ではなく SSH で接続している場合に、起きやすいようです。

何度 push しても失敗する場合は Bitbucket LFS Media Adapter を使うのが有効です。

Bitbucket LFS Media Adapter の導入方法

Bitbucket LFS Media Adapter のページから Linux 64-bit 用のファイルをダウンロードします。

ファイルを展開し、git-lfs-bitbucket-media-api の実行ファイルをどこか適当な場所に配置します。

# ファイルの解凍
$ unzip GitLfsBitbucketAdapter-linux-amd64-1.0.6.zip
# 例えば /usr/local/bin/ にコピーする
$ sudo cp GitLfsBitbucketAdapter-linux-amd64-1.0.6/git-lfs-bitbucket-media-api /usr/local/bin/

そして、 git 側の設定で BitBucket に Git LFS でファイルを転送する場合に Bitbucket LFS Media Adapter を利用するように設定します。

# 例えば /usr/local/bin/git-lfs-bitbucket-media-api に置いた場合
$ git config --global lfs.customtransfer.bitbucket-media-api.path /usr/local/bin/git-lfs-bitbucket-media-api

あとは通常通り、 git lfs track large-file.zip とか git push すれば、 Bitbucket LFS Media Adapter を使ってファイルを転送してくれます。

Bitbucket LFS Media Adapter の利点

公式ページによると Bitbucket LFS Media Adapter は以下のような特徴があるとのこと。

  • アップロード・ダウンロードを中断&再開できる
  • 大きなファイルを分割して転送
  • 並列で転送することで転送時間を短縮できる
  • ファイルに変更があった場合のみ再転送が行われる
  • Git コマンドに対して特に変更が必要ない

便利ですね!

参考URL

python の multiprocecssing.Pool.map で複数の引数を持つ関数を扱う

python の multiprocessing を用いてマルチスレッド処理を行う際に、複数の引数を持つ関数を扱うときの Tips です。

動作環境

方法

やり方は簡単で、目的となる関数をラップするだけです。

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

from multiprocessing import Pool


def calc(a, b, c):
    result = a + b * c
    print("%d + %d * %d = %d" % (a, b, c, result))
    return result


def wrap_calc(num):
    return calc(*num)


def main():
    pool = Pool(processes=4)
    args = [(1, 2, 3), (2, 3, 4), (3, 4, 5), (4, 5, 6)]
    print("result = %s" % pool.map(wrap_calc, args))


if __name__ == '__main__':
    main()

結果

$ python pool.py 
1 + 2 * 3 = 7
2 + 3 * 4 = 14
4 + 5 * 6 = 34
3 + 4 * 5 = 23
result = [7, 14, 23, 34]

上記のように、wrap_calc メソッドにリスト型で引数を渡し calc メソッドに展開してあげれば解決します。

参考URL

ansible でネストされた item に対してループを回す

動作環境

  • ansible 2.1

with_subelements でネストされたループを回す

with_items のかわりに with_subelements を利用することで、ネストされた item に対してループを回すことが出来ます。

vars/main.yml

users:
  - sam:
    email:
      - sam@example.com
      - sam@example.jp
  - mary:
    email:
      - mary@example.com
  - mike:
    email:
      - mike@example.com
      - mike@example.net

tasks/main.yml

- name: print email addresses
  debug: msg="{{ item[1] }}"
  with_subelements:
    - "{{ users }}"
    - email

実行結果

ok: [localhost] => (item=({u'sam': None}, u'sam@example.com')) => {
    "item": [
        {
            "sam": null
        }, 
        "sam@example.com"
    ], 
    "msg": "sam@example.com"
}
ok: [localhost] => (item=({u'sam': None}, u'sam@example.jp')) => {
    "item": [
        {
            "sam": null
        }, 
        "sam@example.jp"
    ], 
    "msg": "sam@example.jp"
}
ok: [localhost] => (item=({u'mary': None}, u'mary@example.com')) => {
    "item": [
        {
            "mary": null
        }, 
        "mary@example.com"
    ], 
    "msg": "mary@example.com"
}
ok: [localhost] => (item=({u'mike': None}, u'mike@example.com')) => {
    "item": [
        {
            "mike": null
        }, 
        "mike@example.com"
    ], 
    "msg": "mike@example.com"
}
ok: [localhost] => (item=({u'mike': None}, u'mike@example.net')) => {
    "item": [
        {
            "mike": null
        }, 
        "mike@example.net"
    ], 
    "msg": "mike@example.net"
}

参考URL

Mac で ROS の環境構築

Mac OSX で ROS を動かすまでの環境構築手順です。

環境

  • Mac OSX El Capitan
  • ROS Kinetic

ROS の環境構築

GUI 系のツールを動かそうとすると Qt5 周りの依存関係でハマったので、とりあえず ROS の基本パッケージのみ(ROS-Comm)の環境構築を行いました。

基本的には公式ページの手順 に則るだけです。

Homebrew の設定

Homebrew を最新版にし cmake をインストールしておきます。

$ brew update
$ brew install cmake

ROS のインストールに必要な依存パッケージをインストールできるようにします。

$ brew tap ros/deps
$ brew tap osrf/simulation
$ brew tap homebrew/versions
$ brew tap homebrew/science

Python, Pip の設定

Homebrew でインストールしたパッケージを Python から使えるようにします。

$ mkdir -p ~/Library/Python/2.7/lib/python/site-packages
$ echo "$(brew --prefix)/lib/python2.7/site-packages" >> ~/Library/Python/2.7/lib/python/site-packages/homebrew.pth

pip が入っていない場合は pip をインストールします。

$ brew install python  # brew Python comes with pip
$ sudo -H python -m pip install -U pip  # Update pip

pip でパッケージをインストールします。

$ sudo -H python -m pip install -U wstool rosdep rosinstall rosinstall_generator rospkg catkin-pkg Distribute sphinx

rosdep の初期化

rosdep をインストールできたら、初期化を行っておきます。

$ sudo -H rosdep init
$ rosdep update

catkin workspace の作成

catkin_ws というディレクトリを作成します。

$ mkdir ~/catkin_ws
$ cd ~/catkin_ws

ROS のインストール

今回は GUI 系のツールなしの、最小限の ROS パッケージのセットをインストールします。

$ rosinstall_generator ros_comm --rosdistro kinetic --deps --wet-only --tar > kinetic-ros_comm-wet.rosinstall
$ wstool init -j8 src kinetic-ros_comm-wet.rosinstall

workspace の初期化が済んだら、依存するパッケージをインストールします。

$ rosdep install --from-paths src --ignore-src --rosdistro kinetic -y

そして workspace 内の各パッケージをビルド、インストールします。

$ ./src/catkin/bin/catkin_make_isolated --install -DCMAKE_BUILD_TYPE=Release

ROSの動作を確認

ターミナルに ROS の環境変数を設定しておきます。

$ source ~/catkin_ws/install_isolated/setup.bash

ROS の動作を確認します。

$ roscore &

$ rosnode list
/rosout

$ rosnode info /rosout
--------------------------------------------------------------------------------
Node [/rosout]
Publications: 
 * /rosout_agg [rosgraph_msgs/Log]

Subscriptions: 
 * /rosout [unknown type]

Services: 
 * /rosout/set_logger_level
 * /rosout/get_loggers


contacting node http://YumaM-iMac-3.local:53388/ ...
Pid: 26340

$ rosparam list
/rosdistro
/rosversion
/run_id

動いた!

参考URL

ROS開発にPyCharmやCLionを使う際のTips

この記事では ROS の開発に Jetbrains 製の IDE である PyCharm や CLion を使う際に、便利に開発を進めるための設定を紹介しています。

環境

  • Ubuntu 16.04 (14.04)
  • ROS Kinetic (Indigo)
  • PyCharm 2016.X
  • CLion 2016.X

環境変数を設定

Ubuntu にインストールした PyCharm や CLion をランチャーから起動すると、ROS の環境変数が読み込まれておらず、ROSの関数やメッセージを import / include すると not found とワーニングが表示されます。

そこで、ROSの環境変数を読み込んだターミナルから IDE を起動してあげることで、メッセージや関数が正しく補完されるようになります。

$ source /opt/ros/kinetic/setup.bash  # ROS Kinetic の場合
$ source /opt/ros/indigo/setup.bash   # ROS Indigo の場合
$ source ~/catkin_ws/devel/setup.bash
$ clion &  # CLion をバックグラウンドで起動
$ charm &  # PyCharm をバックグラウンドで起動

追記(2016/10/27)

以下のように Unity の launcher ファイルを書き換えることで、シェルから IDE を立ち上げる必要がなくなります。

PyCharmの場合 ~/.local/share/applications/jetbrains-pycharm.desktop CLionの場合 ~/.local/share/applications/jetbrains-clion.desktop

[Desktop Entry]
Version=1.0
Type=Application

...

# 以下の行を削除
Exec=bash -c "/path/to/your/clion/bin/pycharm.sh %f"  # PyCharm
Exec=bash -c "/path/to/your/clion/bin/clion.sh %f"  # CLion

# 以下の行を追記する(PyCharm, ROS Kinetic の場合)
Exec=bash -c "source /opt/ros/kinetic/setup.bash; source /path/to/your/catkin_ws/devel/setup.bash; /path/to/your/pycharm/bin/pycharm.sh" %f

# 以下の行を追記する(CLion, ROS Kinetic の場合)
Exec=bash -c "source /opt/ros/kinetic/setup.bash; source /path/to/your/catkin_ws/devel/setup.bash; /path/to/your/clion/bin/clion.sh" %f

...

型ヒントを利用 (PyCharm)

Python の docstring に変数や戻り値の型を記述すると、PyCharm がメンバ変数の補完や型の誤りの指摘をしてくれます。

例えば、PoseStamped 型のトピックのコールバック関数を例に取るとこんな感じです。

import math

import rospy
from geometry_msgs.msg import PoseStamped

def callback_pose(pose):
    u""" PoseStamped のトピックのコールバック

    :param geometry_msgs.msg.PoseStamped pose: 変数 pose に関する説明
    :rtype: float  # 関数の戻り値の型
    :return: pose の原点からの距離  # 関数の戻り値の説明
    """
    # pose. と打つと pose を補完、 pose.pose と打つと position や orientation を補完してくれる
    position = pose.pose.position
    distance = math.sqrt(position.x ** 2 + position.y ** 2 + position.z ** 2)
    return distance


rospy.Subscriber("/some/topic", PoseStamped, callback_pose)

ROS の Pose 型と PoseStamped 型などは間違いやすいうえ、Python だと実行するまで気づけなかったりするので、PyCharm の type hinting を活用するとミスが減って効率アップできます。

参考URL

FTDI FT2232C用のudevルール

FTDIのFT2232C (Dual RS-232)というUSBシリアルを接続した際に、他のデバイスと識別できるよう、/dev/以下にシンボリックリンクを作成するudevのルールです。

通常のUSBデバイスならば、Vendor IdとProduct Idを指定すれば良いのですが、FT2232Cは2つのシリアルポートが存在するため、少し工夫が必要です。

環境

USBデバイスとして認識していることを確認

lsusb コマンドを実行して、 ベンダーIDとプロダクトIDが0403, 6010なるデバイスが存在することを確認します。

$ lsusb | grep "0403:6010"
Bus XXX Device XXX: ID 0403:6010 Future Technology Devices International, Ltd FT2232C Dual USB-UART/FIFO IC

udevルールの作成

99-ft2232c.rulesというファイルを以下の内容で作成します。

# udev rule for FT2232C (Dual USB-UART/FIFO IC)
ACTION=="add", SUBSYSTEMS=="usb", ATTRS{interface}=="Dual RS232", SYMLINK+="ft2232c-%s{bInterfaceNumber}"

作成したファイルを /etc/udev/rules.d/以下にコピーします。

$ sudo cp 99-ft2232c.rules /etc/udev/rules.d/

シンボリックリンクが貼られたことを確認

USBケーブルを抜き差しすると、 /dev/ft2232c-00, /dev/ft2232c-01 として、2つのシリアルポートが認識されていることが確認できます。

$ ls -al /dev/ | grep USB
lrwxrwxrwx  1 root root           7  7月 25 18:48 ft2232c-00 -> ttyUSB0
lrwxrwxrwx  1 root root           7  7月 25 18:48 ft2232c-01 -> ttyUSB1
crw-rw-rw-  1 root dialout 188,   0  7月 25 14:07 ttyUSB0
crw-rw----  1 root dialout 188,   1  7月 25 18:53 ttyUSB1

参考URL

ROS Pythonでオイラー角とクォータニオンの相互変換

ROSでオイラー角とクォータニオンを変換するには、tfパッケージの関数を利用すれば良いのですが、 単体の関数として使うには少々使いづらいので、簡単なラッパー関数を作りました。

オイラー角からクォータニオンへの変換

import tf
from geometry_msgs.msg import Quaternion

def euler_to_quaternion(euler):
    """Convert Euler Angles to Quaternion

    euler: geometry_msgs/Vector3
    quaternion: geometry_msgs/Quaternion
    """
    q = tf.transformations.quaternion_from_euler(euler.x, euler.y, euler.z)
    return Quaternion(x=q[0], y=q[1], z=q[2], w=q[3])

実行例

>>> import math
>>> euler_to_quaternion(Vector3(0.0, 0.0, 0.0))
x: 0.0
y: 0.0
z: 0.0
w: 1.0

>>> euler_to_quarternion(Vector3(0.0, 0.0, math.pi / 2.0))
x: 0.0
y: 0.0
z: 0.707106781187
w: 0.707106781187

クォータニオンからオイラー角への変換

import tf
from geometry_msgs.msg import Vector3

def quaternion_to_euler(quaternion):
    """Convert Quaternion to Euler Angles

    quarternion: geometry_msgs/Quaternion
    euler: geometry_msgs/Vector3
    """
    e = tf.transformations.euler_from_quaternion((quaternion.x, quaternion.y, quaternion.z, quaternion.w))
    return Vector3(x=e[0], y=e[1], z=e[2])

実行例

>>> quaternion_to_euler(Quaternion(0.0, 0.0, 0.0, 1.0))
x: 0.0
y: -0.0
z: 0.0

>>> quaternion_to_euler(Quaternion(0.0, 0.0, 0.7071, 0.7071))
x: 0.0
y: -0.0
z: 1.57079632679

参考URL