冪集合の空集合含まない奴は何ていうの?

プログラム書いていて冪集合なんだけど空集合はいらない。
できたら要素が多い順に出して欲しいって時は無いでしょうか。
私はさっきそう思いました。
空集合(power set)はitertoolsのレシピから

def powerset(iterable):
    "powerset([1,2,3]) --> () (1,) (2,) (3,) (1,2) (1,3) (2,3) (1,2,3)"
    s = list(iterable)
    return chain.from_iterable(combinations(s, r) for r in range(len(s)+1))

とかけます。
コード書く上で空集合が邪魔かつ要素が多い順に出して欲しい場合はこうかなと思います。

@staticmethod
def _powerset(iterable):
    s = list(iterable)
    return chain.from_iterable(combinations(s, r) for r in range(len(s) + 1, 0, -1))

で、空集合を含まない冪集合って何て言うんですかね…。
ありそうなもんですが。

What is shortest?

NetworkXでshortest_pathというメソッドがある。
shortest_path — NetworkX 1.10 documentation

weightのところを見るとweight=でweightを入れるとweight考慮しますと書いてある。
では
add_weighted_edges_from — NetworkX 1.10 documentation
を使って予めweightを設定した場合は?

少し試してみたが、weightは考慮されないようである。
shortest_pathの実装はshortest_path自体の引数がNoneか否かで呼び出すアリゴリズムを選択している。
https://github.com/networkx/networkx/blob/master/networkx/algorithms/shortest_paths/generic.py#L41

sourceとtargetのみ指定すると
bidirectional_shortest_pathが使用されるが、これがunweightedなモジュールの中に含まれている。
実装を見てもweightを自分で計算してそう。

まぁ、bidi rectional_dijkstraをshortest_pathの代わりに使用すればweightが考慮されるようになる。
こう、教訓としてはアルゴリズムは明示的に指定しましょうという。
まぁ、これくらいは見てくれてもいいんじゃないかな感はあるんですがどうなんですかね。

MacOSX Yosemiteでプロファイラを実行する

最近Mac上でC++を書いている。
プロファイラをかけようと思ったが意外に上手く行かなかったのでメモ。

上手くいった奴

Instruments

Apple純正。ビルド時のオプションは不要。
実行時に以下のようにする。

iprofiler -timeprofiler ./a.out

a.dtpsというディレクトリが生成される。
これをXcode付属のInstrumentsに読み込ませる。
Xcodeを立ち上げてメニューのXcode->Open Developer Tool->Instrumentsで起動するか、
Xcode.app/Contents/Applications/Instrumentsで直接実行するかして起動する。
先ほどのa.dtpsを読みこませればプロファイル結果をGUIで見れる。

上手く行かなかった奴

GNU gprof

g++ -pg main.cpp

で生成された実行体を実行してもgmon.outが生成されない。
clang、gccともに変わらず…。

gperftools

g++ -lprofiler main.cpp

a.outが生成される。
a.profにプロファイル情報を吐くようにする。

CPUPROFILE=a.prof ./a.out 

CPUPROFILE=a.profと./a.outを別々に実行するとa.profが生成されなかった。
このプロファイル結果をpprofでみるのだが、メソッド名が16進の文字列になる。

pprof a.out a.prof

原因はASLRにあるらしい。
コンパイル時に-Wl,-no_pieを追加。
これにより一部のメソッド名は正しく表示されるが大半は16進のまま。
そもそも呼んでないメソッド名が処理されていることになっているのでちょっとダメっぽい。

OS X Lion Heap profiling requires disabling Position Independent Executable · Issue #363 · gperftools/gperftools · GitHub
OS X requires disabling Position Independent Executable · Issue #565 · gperftools/gperftools · GitHub

ROS meets Docker

MacOS Yosemite上のDocker内のROSからArduinoにシリアル通信する。
ROSを使う時、apt-getとか使うとシステムがいっぱい汚れる。
辛みしかないのでDockerを使う。
ROSもpythonのvirtualenvみたいのあるよ!ってことなら教えて欲しいです。

Dockerをインストールする

基本的に公式に従う
Installation on Mac OS X

やることは下記からpkgを落としてきてインストールするだけ。
Release v1.5.0 · boot2docker/osx-installer · GitHub

boot2dockerのアイコンができるのでそれをクリックするとターミナルが立ち上がる。*1
VirtualBox上にboot2dockerという名前でLinuxが走るので、この上でゲストOSを走らせることになる。

USBの設定

このままではUSBが使えないので設定をする。

VirtualBox上からboot2dockerを終了させる

右クリック->閉じる->電源オフでいいと思います。

Extension Packをインストールする

下記からExtension Packをダウンロードしてきてインストールする。
Downloads – Oracle VM VirtualBox

boot2dockerの設定を変更する

VirtualBoxGUI上にあるUSBの項目のチェックボックスを入れる。
右のプラスアイコンからフィルターの項目を追加できる。
このフィルターというのが認識させるUSBデバイスになるので認識させたいデバイスを追加する。

Docker imageを作成する

ubuntuのイメージの取得

ゲストOSとしてubuntuを使用したいためこのイメージをダウンロードする。
boot2dockerのアイコンをクリックする。
立ち上がったbashから下記でimageをダウンロードする。

docker pull ubuntu:trusty

imageの一覧は下記になるので、欲しいバージョンに合わせて書き換えて欲しい。
Docker Hub

以下でローカルのimageの一覧が見れる。

docker images

ROS用imageの作成

適当なディレクトリにDockerfileというファイルを作る。
ファイルの中身は下記のように、imageの作成にあたり実行して欲しいスクリプトを書く。

# install ROS indigo
# based ubuntu 14.04 trusty
FROM ubuntu:trusty
 
# prepare install ROS
RUN apt-get update -q \
    && apt-get install -yq wget
 
# install ROS
RUN sh -c 'echo "deb http://packages.ros.org/ros/ubuntu trusty main" > /etc/apt/sources.list.d/ros-latest.list'
RUN wget https://raw.githubusercontent.com/ros/rosdistro/master/ros.key -O - | sudo apt-key add -
RUN apt-get update \
    && apt-get install -y ros-indigo-desktop-full \
    python-rosinstall
 
RUN rosdep init 
 
# vnc
RUN apt-get install -y x11vnc xvfb
# create passwd after create working user
 
# develop env
RUN apt-get install -y byobu \
    zsh \
    git
    
# create user
RUN adduser --disabled-password --gecos '' --shell `which zsh` rosuser
RUN adduser rosuser sudo
RUN echo '%sudo ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers
USER rosuser
WORKDIR /home/rosuser
 
# user indivisual developing env
## vnc
RUN mkdir .vnc
RUN x11vnc -storepasswd 1234 ~/.vnc/passwd
 
# ros env
RUN rosdep update
RUN echo "source /opt/ros/indigo/setup.zsh" >> ~/.zshrc

このDockerfile内で全てやらないといけないかというとそうではなく、
docker commitしてもimageに反映されるのでそれだけで作っても良い。
ただ、秘伝のimageになるのを避けるため、なるべくDockerfileに書きましょう。

以下でhogeという名前のimageがDockerfileから作られる。

 docker build -t hogeimage .

プロセスの作成

USBを使いたいのでboot2dockerがUSBをどこで認識してるか確認する。
下記でboot2dockerの中に入れる。

boot2docker ssh

適当にls /dev/tty*とかでそれっぽいのを探す。
今回は/dev/ttyACM0でした。

以下でプロセスを作成する。
vnc用にportとUSB用にdeviceを指定している。
これでゲストOS上で/dev/ttyUSB0にUSBがマウントされる。

docker run -it -p 5900 --device=/dev/ttyACM0:/dev/ttyUSB0:rwm  --name hogeprocess hogeimage

実行するとゲストOSに入る。
rosuserでUSBを使いたいのでdeviceにchmodしておく。

chmod 666 /dev/ttyUSB0

ゲストOSから抜けるときはexitで抜けれる。
再度入りたいときでプロセスが生きている場合(docker ps -aして、まだいる場合)
下記で入れる。

docker start -i hogeprocess

Arudinoの準備

Arudino用のros_libを作成する。
rosserial_arduino/Tutorials/Arduino IDE Setup - ROS Wiki

docker cpでros_libをMacOSにコピー、Arudino IDEに読み込ませる。
ros_libの中にサンプルコードが入っているので、BlinkというのをArudinoに焼く。

通信

ほぼここに従う
rosserial_arduino/Tutorials/Blink - ROS Wiki

rosuserになって下記を実行する。*2*3

roscore
rosrun rosserial_python serial_node.py _port:=/dev/ttyUSB0

ここでうまくいくとArudinoのRXとTXがチカチカし始める。
下記を実行するとNo13のLEDの付けたり消したりできる。

rostopic pub toggle_led std_msgs/Empty --once


この記事を書くためにboot2docker立ち上げたり落としてたりしたらプロセスに入れなくなった。
docker commitでイメージにしましょうという教訓を得た。

*1:byobu設定してるとターミナルがどっかいっちゃうのbyobuの自動起動解除しとくと良さそう

*2:別にrootでやっても良いですが…

*3:byobuとか使うと良い

django-admin.pyの所在

django1.7に上げた時,お前のsettings.py古くね?それ1.6より前のやつっしょ?って言われて衝撃を受けたので調べたら/usr/local/bin以下の奴使ってた.

virtualenv上でdjango入れたらenvのroot/binのディレクトリの中にdjango-admin.pyが置かれるのでソレ使いましょう.

pipは普通に使っても仮想環境のbinが使われるのでようわからん.
どっか設定抜けてるんですかね.

Gazeboでkobukiを二台出す

Xubuntu12.04上のHydro上でkobukiを二台だす.

前提として
http://wiki.ros.org/kobuki_gazebo
でkobukiが一台出せているとします.

同じ感じでlaunchファイルを作ります.
ワークスペース

catkin_create_pkg hoge
roscd kobuki_gazebo

してkobuki_gazeboに移動,以下をhogeへコピーします
/launch/includes/*.xml
/launch/turtlebot_empty_world.launch
/worlds/empty.world

package.xmlのrun_dependをコピーします.

これで

roslaunch hoge turtlebot_empty_world.launch

すると一台のkobukiが出るはず.
まぁ,この時点ではincludes以下のxmlは参照してないのですが.

/launch/turtlebot_empty_world.launch
を以下のように編集します.
findの参照先に注意してください.

<launch>
  <include file="$(find gazebo_ros)/launch/empty_world.launch">
    <arg name="use_sim_time" value="true"/>
    <arg name="debug" value="false"/>
    <arg name="world_name" value="$(find hoge)/worlds/empty.world"/>
  </include>

  <arg name="base"      value="$(optenv TURTLEBOT_BASE kobuki)"/> <!-- create, roomba -->
  <arg name="battery"   value="$(optenv TURTLEBOT_BATTERY /proc/acpi/battery/BAT0)"/>  <!-- /proc/acpi/battery/BAT0 --> 
  <arg name="stacks"    value="$(optenv TURTLEBOT_STACKS hexagons)"/>  <!-- circles, hexagons --> 
  <arg name="3d_sensor" value="$(optenv TURTLEBOT_3D_SENSOR kinect)"/>  <!-- kinect, asus_xtion_pro --> 

  <group ns="r1">
    <include file="$(find hoge)/launch/includes/$(arg base).launch.xml">
      <arg name="base" value="$(arg base)"/>
      <arg name="stacks" value="$(arg stacks)"/>
      <arg name="3d_sensor" value="$(arg 3d_sensor)"/>
      <arg name="robot_name" value="r1"/>
      <arg name="init_pose" value="-x 1 -y 1 -z 0"/>
    </include>
    <node pkg="robot_state_publisher" type="robot_state_publisher" name="robot_state_publisher">
      <param name="publish_frequency" type="double" value="30.0" />
    </node>
  </group>
  
  <group ns="r2">
    <include file="$(find hoge)/launch/includes/$(arg base).launch.xml">
      <arg name="base" value="$(arg base)"/>
      <arg name="stacks" value="$(arg stacks)"/>
      <arg name="3d_sensor" value="$(arg 3d_sensor)"/>
      <arg name="robot_name" value="r2"/>
      <arg name="init_pose" value="-x 1 -y 4 -z 0"/>
    </include>
    <node pkg="robot_state_publisher" type="robot_state_publisher" name="robot_state_publisher">
      <param name="publish_frequency" type="double" value="30.0" />
    </node>
  </group>
</launch>

/launch/includes/kobuki.launch.xml
を以下のように編集します

<launch>
  <arg name="base"/>
  <arg name="stacks"/>
  <arg name="3d_sensor"/>
  <arg name="robot_name"/>
  <arg name="init_pose"/>

  <arg name="urdf_file" default="$(find xacro)/xacro.py '$(find turtlebot_description)/robots/$(arg base)_$(arg stacks)_$(arg 3d_sensor).urdf.xacro'" />
  <param name="robot_description" command="$(arg urdf_file)" />

  <!-- Gazebo model spawner -->
  <node name="spawn_turtlebot_model" pkg="gazebo_ros" type="spawn_model"
        args="$(arg init_pose) -unpause -urdf -param robot_description -model $(arg robot_name)"/>

  <!-- Velocity muxer -->
  <node pkg="nodelet" type="nodelet" name="mobile_base_nodelet_manager" args="manager"/>
  <node pkg="nodelet" type="nodelet" name="cmd_vel_mux"
        args="load yocs_cmd_vel_mux/CmdVelMuxNodelet mobile_base_nodelet_manager">
    <param name="yaml_cfg_file" value="$(find turtlebot_bringup)/param/mux.yaml" />
    <remap from="cmd_vel_mux/output" to="mobile_base/commands/velocity"/>
  </node>

  <!-- Bumper/cliff to pointcloud (not working, as it needs sensors/core messages) -->
  <include file="$(find turtlebot_bringup)/launch/includes/kobuki/bumper2pc.launch.xml"/>
</launch>

これで

roslaunch hoge turtlebot_empty_world.launch

すると二台のkobukiが出るはず.
要はそれぞれのモデルに名前をつけてくださいという,チュートリアルにもあったことです.

動かすには以下の様な感じでscriptsを作ってrosrunすればいいです.
dependencyにrospyとgeometry_msgs追加してください.

import rospy
from geometry_msgs.msg import Twist

if __name__=="__main__":
        rospy.init_node('it')

        p=rospy.Publisher('r1/commands/velocity',Twist)
        twist = Twist()
        twist.linear.x = -0.5;
        twist.linear.y = 0.0;
        twist.linear.z = 0.0;

        twist.angular.x = 0.0;
        twist.angular.y = 0.0;
        twist.angular.z = 0.0;
        for i in range(10):
                p.publish(twist);
                rospy.sleep(0.5)

フォーマッタとか色々設定してないので汚いのは容赦してほしい.
仮想マシン上のそういう設定全くやる気が起きないんだよなぁ….

Install ROS on MacOS X Mavericks

ROS hydroをMacOS X Mavericks上にインストールする.


諦めました.
これがなんとかならんと無理です.
Mavericks周りは今色々直してくれてる最中らしいのでもう少し待ちましょう!
https://github.com/orocos/orocos_kinematics_dynamics/pull/4

以下諦めたログ

homebrewを使用したインストールが選択できるのでhomebrewを使用する.

大まかな流れはインストレーションマニュアルに従う.
http://wiki.ros.org/hydro/Installation/OSX/Homebrew/Source

コケた時の対処法

Resolving Dependenciesの前に

Resolving Dependenciesで

rosdep install --from-paths src --ignore-src --rosdistro hydro -y

するが,これで色々pip installされる.ここでコケる.
こけたらbrew install -v hogeする.

pip install -U PIL

PILのコンパイル時にfreetypeが無いと言われる.brewfreetype入れるとfreetype2になるせい.
http://stackoverflow.com/questions/20325473/error-installing-python-image-library-using-pip-on-mac-os-x-10-9

ln -s /usr/local/include/freetype2 /usr/local/include/freetype

をすると通る.

pip install -U pcl

pclなんてFormulaは無いと言われる.

brew tap ros/hydro

をしていないため.手順書ちゃんと読みましょう.

brew install ogre

brew install -v ogreするとfreetypeでコケている.
freetypeのリンクにコケる.uninstall & installしたら通った.
よくわからん.
https://github.com/osrf/homebrew-simulation/issues/4

brew install gazebo

最新のgazeboだとfixされているらしいので

brew install gazebo --HEAD

をする.
https://github.com/osrf/homebrew-simulation/issues/5

brew install PyQwt

PyQwtがpyqtの新しい設定フォーマットに追従していないのが原因.
pyqtをダウングレードしてPyQwtを入れる.
https://github.com/Homebrew/homebrew/issues/25224
http://sourceforge.net/p/pyqwt/bugs/12/