冪集合の空集合含まない奴は何ていうの?
プログラム書いていて冪集合なんだけど空集合はいらない。
できたら要素が多い順に出して欲しいって時は無いでしょうか。
私はさっきそう思いました。
空集合(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++を書いている。
プロファイラをかけようと思ったが意外に上手く行かなかったのでメモ。
上手くいった奴
上手く行かなかった奴
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の設定を変更する
VirtualBoxのGUI上にある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
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でイメージにしましょうという教訓を得た。
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が無いと言われる.brewでfreetype入れると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 PyQwt
PyQwtがpyqtの新しい設定フォーマットに追従していないのが原因.
pyqtをダウングレードしてPyQwtを入れる.
https://github.com/Homebrew/homebrew/issues/25224
http://sourceforge.net/p/pyqwt/bugs/12/