LanguageClient-neovim(cquery)で補完を有効にするため,colcon(ROS2)のワークスペースにcompile_commands.jsonを配置する

中小規模のpackageではvimで手軽に書きたい!!

(neo)vimC++を書く時,ROS2のような外部ライブラリはパスを設定しておかないと補完が効きません. neovim + LanguageClient-neovim (cquery) 環境では,cmake (or colcon build )の引数で CMAKE_EXPORT_COMPILE_COMMANDS をつけた際に生成されるcompile_commands.jsonプロジェクト下にあるといい感じに補完してくれます.

colcon build --cmake-args -DCMAKE_EXPORT_COMPILE_COMMANDS=1

生成されるcompile_commands.jsonの例

[
{
  "directory": "/path_to_colcon_ws/ros2_ws/build/examples_rclcpp_minimal_publisher",
  "command": "/usr/bin/clang++   -I/opt/ros/dashing/include    -Wall -Wextra -Wpedantic -std=gnu++14 -o CMakeFiles/publisher_lambda.dir/lambda.cpp.o -c /path_to_colcon_ws/ros2_ws/src/examples/rclcpp/minimal_publisher/lambda.cpp",
  "file": "/path_to_colcon_ws/ros2_ws/src/examples/rclcpp/minimal_publisher/lambda.cpp"
},
{
  "directory": "/path_to_colcon_ws/ros2_ws/build/examples_rclcpp_minimal_publisher",
  "command": "/usr/bin/clang++   -I/opt/ros/dashing/include    -Wall -Wextra -Wpedantic -std=gnu++14 -o CMakeFiles/publisher_member_function.dir/member_function.cpp.o -c /path_to_colcon_ws/ros2_ws/src/examples/rclcpp/minimal_publisher/member_function.cpp",
  "file": "/path_to_colcon_ws/ros2_ws/src/examples/rclcpp/minimal_publisher/member_function.cpp"
},
{
  "directory": "/path_to_colcon_ws/ros2_ws/build/examples_rclcpp_minimal_publisher",
  "command": "/usr/bin/clang++   -I/opt/ros/dashing/include    -Wall -Wextra -Wpedantic -std=gnu++14 -o CMakeFiles/publisher_not_composable.dir/not_composable.cpp.o -c /path_to_colcon_ws/ros2_ws/src/examples/rclcpp/minimal_publisher/not_composable.cpp",
  "file": "/path_to_colcon_ws/ros2_ws/src/examples/rclcpp/minimal_publisher/not_composable.cpp"
}
]

f:id:DeanKH:20191015225057p:plain
vim上での補完例

ですが,各パッケージのcompile_commands.jsonは,colcon build した場所に生成されるbuild/{project name}/の下に生成されます.そのため,補完を有効にするためにはsrc/{package name}/の下に持ってくる必要があります1.この場合はシンボリックリンクでOK. 以下に置いたのは,そのためのスクリプトです.

コード

gist.github.com

スクリプトについて

気が向いたらします.

課題

おわりに

他に何かいい方法はあるのだろうか...


  1. vim-lspかcqueryでパスを指定すれば直下にいなくても大丈夫なようですが,各プロジェクトのcompile_commands.jsonのパスを指定するのはメンドイ

Gazeboで外部モデルロード時の設定

はじめに

gazeboのworldにオブジェクトを追加する際,osrfのモデルレポジトリから引っ張ってきますが,初期ロード時にダウンロードしてキャッシュするため時間がかかります. そこで,予めレポジトリをローカルにcloneしてそこを指定するようにします[1].

手順

1. レポジトリを任意の場所(私は~/workSpace/data/)にクローン

hg clone https://bitbucket.org/osrf/gazebo_models ~/workSpace/data/

2. 環境変数の設定

クローンしてきたレポジトリへのパスを通します.モデル関係の環境変数GAZEBO_MODEL_PATHのようなので[2],自分の使用しているshellに書きます.

export GAZEBO_MODEL_PATH='$HOME/workSpace/data/gazebo_models/'

3.worldファイルの設定

上記パスを優先して読んでくれるようなので,

<sdf version="...">
  <!-- other tags -->
  
  <include>
    <uri>model://wooden_board</uri>
    <name>gas_station</name>
    <pose>5.0 5.0 0 0 0 0</pose>
  </include>
  
  <!-- other tags -->
</sdf>

おわり

参考リンク

  1. Gazebo : Tutorial : Model structure and requirements
  2. https://bitbucket.org/osrf/gzweb/issues/45/creating-local-model-of

KDLを使ってみました

後で追加

KDLを使ってマニピュレータのヤコビ行列を取得する際の注意点

KDL::Chainがある状態で以下の関数を呼び出すとヤコビ行列が取得できます.(便利)

KDL::ChainJntToJacSolver::JntToJac(KDL::JntArray,KDL::Jacobian&);

ヤコビ行列を受け取るクラスKDL::Jacobianを初期化しておかないと結果が入らないっぽい? 以下のように4行目のJacobianのコンストラクタにジョイントの数を渡すとJntToJacで受け取れました.

KDL::Chain chain;
KDL::JntArray q;
//...
KDL::Jacobian J(chain.getNrOfJoints());
KDL::ChainJntToJacSolver jsolver(chain);
jsolver.JntToJac(q, J);

XPS13 (9360) を買いました

年末セールで安かったので DellのXPS13を買いました.15%OFFクーポン使って約2万円引き.

www.dell.com

家にも研究室にも程々に真っ当なデスクトップがあるので
i5, FHD, 8GB, 256GBを購入.

到着して早々にパーティション縮小してUbuntuを入れました.

  1.  BIOSRAIDモードをAHCIに変更,secure bootをoff
  2. リカバリドライブでWindowsを修復 (モード変更でwindowsが死ぬため)
  3. Windows上でパーティション縮小,BIOSのアップデート
  4. Ubuntu入れる
  5. secure bootをon

インストール時に一部ドライバが入れられないのでsecure bootを切る.

linux kernel は4.4 -> 4.8 -> 4.9
4.8で起動時に無線の立ち上げに失敗したので以下のビルド済みパッケージを入れた.
http://kernel.ubuntu.com/~kernel-ppa/mainline/v4.9/

Buffaloの5GHz対応無線ルータのSSID隠し (ANY接続をOFF) 状態で接続できない問題が発生.仕方がないのでANY接続状態に変更して対応.

XPSは海外だとDeveloper Editionと称してOSがUbuntu構成のものを売っているので,変なことにはならないだろうと高を括って買ったので一安心.
昨年の夏に買ったSurface Pro4は色々独自構成だったので不安定過ぎた.有志の方々の頑張りで,keyboard, touch pad, pen, touch screen等が使えるようになったけど色々ツラかった.

Bundle Adjustment のためのcvsbaをROS (catkin)で使うために

はじめに

SfM(Structure from Motion)とかいう単眼カメラを用いた三次元形状復元+自己位置推定手法を実装するためには, Bundle Adjustmentという多画像からパラメータ,3次元形状を推定する工程を実装する必要があるようです[1].
自己実装は面倒なので,OpenCVを用いて実装されたcvsba[2]というライブラリがあるのでそれを使います.

インストール

Ubuntuへのインストールは公式サイト[2]見ればいいので省略します.
ROS(catkin)で使用するためCMakeLists.txtには,以下の様に書けば動作するようです[3].

cmake_minimum_required(VERSION 2.8.3)
project(local_test)

find_package(catkin REQUIRED COMPONENTS
  roscpp
)
find_package(OpenCV REQUIRED)
LINK_LIBRARIES(cvsba)

catkin_package(
#  INCLUDE_DIRS include
#  LIBRARIES local_test
#  CATKIN_DEPENDS roscpp rospy
#  DEPENDS system_lib
)

include_directories(
  ${catkin_INCLUDE_DIRS}
  ${OpenCV_iNCLUDE_DIRS}
)

 add_executable(cvsba_test src/cvsba_test.cpp)

 target_link_libraries(cvsba_test
   ${catkin_LIBRARIES}
   ${OpenCV_LIBRARIES}
 )

OpenCV関係に加えて

LINK_LIBRARIES(cvsba)

の一文を加えれば良いようです.

参考文献

  1. 3次元復元のためのバンドル調整の実装と評価
  2. cvsba
  3. 理科系の備忘録,sample CMakeLists.txt

Atom Setup Manual

1. Atomのインストール

AtomはGitGubが開発したマルチプラットフォーム (Ubuntu, Windows) テキストエディタ
拡張機能 (Package)を入れることで様々なコードを書きやすくなる.
C++, Python, Latex, markdownなど.

AtomAtom Official Page からダウンロードできる もちろん,Ubuntuユーザーはapt-getでインストールできる.

apt-get install atom

2. 基本設定

Atomを使うために幾つか設定が必要.

文末スペース自動削除機能のOFF

markdown エディタとして使う際,デフォルトの文末スペース自動削除は余計なおせっかい.
この機能を切るためには,
'Ctrl + ,' でSettingsを開き,Packageタブで拡張機能"Whitespace"の設定を開く.
そして"Remove Trailing Whitespace"のチェックボックスを外せばOK.

フォント設定

デフォルトの(日本語)フォントは汚い. なので変更します.
メニューバーの Edit -> Stylesheet を開いて任意の対象内でfont-familyを記述する.
複数書いておけば優先順位の高いフォントが存在しなかった時に 左から順に参照してくれる.

hoge{
  font-family: "Yu Gothic", 'Ubuntu';
}

自分の設定はこんな感じ

// style the background color of the tree view
.tree-view {
  font-family: "Yu Gothic", 'Ubuntu'
  // background-color: whitesmoke;
}

.markdown-preview{
  font-family:"Yu Gothic", 'Ubuntu', "MS ゴシック";
}
// style the background and foreground colors on the atom-text-editor-element itself
atom-text-editor {
  font-family: "Yu Gothic", 'Ubuntu';
  color: white;
  // background-color: hsl(180, 24%, 12%);
}

// To style other content in the text editor's shadow DOM, use the ::shadow expression
atom-text-editor::shadow .cursor {
  // border-color: red;
}

3. Packages Installation

自分の主な用途はmarkdown editorなのでそれ中心. + color-picker + file-icons + markdown-pdf + markdown-scroll-sync
markdownのsourceとpreviewの位置を同期してくれる
+ minimap
sourceのスクロールがでかくなる?
+ minimap-autohide
code書いている時にminimapを隠してくれる.
+ toggle-markdown-task

4. Themes Installation

  • atom-material-ui
    android(5.0 Lolipop)から導入されたMaterial Designぽくなる.

UML

この当たりを参考に環境構築
デフォルトの色設定が気に入らなかったのでまとめて設定

skinparam backgroundColor #e6e6e6

skinparam classBorderColor #1a1a1a
skinparam classBackgroundColor white
skinparam classArrowColor #1a1a1a
skinparam stereotypeCBackgroundColor white

skinparam classAttributeFontColor black
skinparam classAttributeFontSize 12
skinparam classAttributeIconSize 9
skinparam classAttributeFontStyle plain
skinparam classAttributeFontName "Ricty Discord"

skinparam classFontColor black
skinparam classFontSize  15
skinparam classFontStyle plain
skinparam classFontName "Ricty Discord"

skinparam defaultFontName "Ricty Discord"

Eigen Mapの使い方

動機

最近何かと話題のROS (Robot Operating System)ですが,私も常用しています.もうやめられません. ROSではプログラムを主にC++Pythonで書きますが,私はC++ばっかり書いてます. Pythonの書き方知らないので

さて,ロボット系では色々な場面で行列演算を行いますが,C++ではEigenという便利な行列演算ライブラリがあります.便利です.わざわざ行列演算にするほどのことでもない計算を,わざわざEigenにやらせてしまいます. その際にC++の配列 (std::vectorなど) からEigenのベクトル型に変換することになります. 今回はその方法について軽く書きます.

書き方-基本-

C++の配列からEigenのベクトルへの変換はEigen::Mapを使います. 変換コードは以下のようになります. (色々飛ばしてます.)

#include <Eigen/Core>

std::vector<double> a(3);
Eigen::VectorXd b = Eigen::Map<Eigen::VectorXd>(&a[0],a.size());

for文で回さなくて済むので重宝してます.

ROSでハマったところ

ROSのコールバック関数で受け取るメッセージはconst指定で受け取らないとコンパイル時にエラーが返されると思います. 受け取ったメッセージ内の配列に対して上記のコードを適用すると,型が違うとコンパイラに怒られます. 調べるのがメンドウだったので今まで関数内で宣言した通常変数にコピーしてからMapを使用していたのですが,さすがに汚いのでgoogle先生に聞いたら普通に出てきました.

Eigen::Map<> on const array • KDE Community Forums

Oops!… 蓋を開けてみれば何てことはなかった.

おまけ

Mapの条件は配列の型が同じで連続していることが条件のようなので,geometry_msgs::Wrenchのようなforce(x,y,z)とtorque(x,y,z)のような,配列の形になってなくても 一気に格納できるようです.

#include <Eigen/Core>

geometry_msgs::WrenchStamped ws;
Eigen::VectorXd b = Eigen::Map<Eigen::VectorXd>(&ws.wrench.force.x,6);

配列の要素が連続であることが保証されているか,内部の仕様を見ておらず確かではないので,あまり良いことではないかもしれません.

参照

http://mikaka.org/~kana/dl/pdf/pdf-eigennote.pdf:行列ライブラリEigenのメモ

Eigen::Map<> on const array • KDE Community Forums

;(function(document){ var pres = document.getElementsByTagName("pre") for(var i=pres.length; i--; ){  var el = makeOl(pres[i]) pres[i].appendChild(el) } function makeOl(pre){ if (pre.className.indexOf("gist") !== -1) { return } var ol = document.createElement("ol") , li = document.createElement("li") , df = document.createDocumentFragment() , br = pre.innerHTML.match(/\n/g) || 0 ol.className = "preLine" ol.setAttribute("role", "presentation") // no lang, no line-number if( pre.className && ! /lang-./.test(pre.className) ){ br.length += 1 } for(var i=br.length; i--; ){ var li2 = li.cloneNode(true) df.appendChild(li2) } ol.appendChild(df) return ol } })(document)