ROS講座99 エラーと対策

# 環境
この記事は以下の環境で動いています。

| 項目 | 値 |
|:-:|:-:|
| CPU | Core i5-8250U |
| Ubuntu | 16.04 |
| ROS | Kinetic |

# 概要
ROSを使っているとROS特有のエラーによく遭遇します。頻出するエラーを並べてみます。

# ビルド時のエラー
catkin_makeするときに出てくるエラーです。

## ROS_INFOなどで型がおかしい
ROSというよりもprintfのが要因ですが、ROS_INFOなどでフォーマット指定子と引数の型が合っていないときにwarningが出ます。

```txt:エラーメッセージ
/opt/ros/kinetic/include/ros/console.h:346:176: warning: format ‘%f’ expects argument of type ‘double’, but argument 8 has type ‘int’ [-Wformat=]
     ::ros::console::print(filter, __rosconsole_define_location__loc.logger_, __rosconsole_define_location__loc.level_, __FILE__, __LINE__, __ROSCONSOLE_FUNCTION__, __VA_ARGS__)
```

```c++:問題の部分
int value = 0;
ROS_INFO("%f", value);
```

## include<***.h>が見つからない
一番単純なのはファイル名が間違っているということですが、ROSでは対象がインクルードディレクトリに追加されていないために参照できないということが多いです。CMakeでfind_packageがないということがあり得ます。

```txt:エラーメッセージ
fatal error: ********.h: No such file or directory
```

```cmake:問題の部分
find_package(catkin REQUIRED COMPONENTS
  roscpp
  # <- includeしているが抜けている物がある。
)
```

## 関数、クラスメンバが「定義されていない」と表示される

```text:エラーメッセージ
main.cpp:(.text+0x72): undefined reference to `******()'
```

大体はCMakeListの`find_package()`か`target_link_libraries()`の書き忘れ。

## package.xmlの設定ミス
以下のようなものが大量に出る。

```text
Error(s):
- The manifest (with format version 2) must not contain the following tags: run_depend
```
packageXMLのversionが間違っている、混ざっている
例：ver2なのに`<run_depend>`と書いている。

<!--
## package.xmlの設定ミス
## CMakeListでfind_package()の忘れ
-->

## package.xmlのdependが足りない。

```text
CMake Error at /home/......./a_pkg/cmake/a_pkg-genmsg.cmake:244 (add_custom_target):
  add_custom_target cannot create target "a_pkg_generate_messages_cpp"
  because another target with the same name already exists.  The existing
  target is a custom target created in source directory
  "/home/......./b_pkg".  See documentation for
  policy CMP0002 for more details.
```

b_pkg/package.xmlに`<depend>a_pkg</depend>`と書く必要があります。

## msgファイルを書き換えた後にcatkin_makeが走らなくなる

```text
The dependencies of the message/service '***_msgs/******' have changed. Please rerun cmake.
```

catkin_ws/buildとcatkin_ws/develを消去してからcatkin_makeをしましょう。

# 実行時

## 自分のIPの設定ミス
ROSを起動するときに`ROS_IP`の値が正しく設定されていないと起こります。ROS_IPが空なら問題はないのですが、ROS_IPに自分のマシンが持っていないIPアドレスが入っていないと問題が起きます。

```text:メッセージ
Unable to contact my own server at [http://192.168.38.158:34301/].
This usually means that the network is not configured properly.

A common cause is that the machine cannot ping itself.  Please check
for errors by running:

	ping 192.168.38.158

For more tips, please see

	http://www.ros.org/wiki/ROS/NetworkSetup

The traceback for the exception was written to the log file
```

```shell:対策
export ROS_IP=""
```

## 設定のされていないpublisherでpublish()した。
そのままです。

```text:エラーメッセージ
[FATAL] [1562943290.857793905]: ASSERTION FAILED
	file = /opt/ros/kinetic/include/ros/publisher.h
	line = 102
	cond = false
	message = 
[FATAL] [1562943290.857847739]: Call to publish() on an invalid Publisher
```

```c++:問題の部分
int main(int argc, char **argv){
  ros::init(argc, argv, "talker");
  ros::Publisher pub;

  std_msgs::Int32 int_msg;
  pub.publish(int_msg);
  return 0;
}
```

## xacroファイル名が間違っている
xacroでファイルが間違っている時はurdfを読むノードがIOErrorを吐きます。赤字でないので気づきにくいです。

```text
IOError: [Errno 2] No such file or directory: u'********/catkin_ws/src/ros_lecture/sim_lecture/urdf/odm_single_wheel_only.urdf'
```

# rosの名前が不正
以下の例だとrosのtopic名として使ってはいけない「スペース」が入っています。

```text:エラーメッセージ
remap to [/XXXX ] is not a valid ROS name
The traceback for the exception was written to the log file
```

## 同じ名前のtopicだがmsgの型が違う
よくリファクタリングの最中などで発生しますね。基本的におかしい状況ですが、状況によってエラーメッセージが変わります。
同じtopic名でmsgの型が異なる複数のpublisherが起動すると以下のエラーが出ます。

```text:エラーメッセージ
[ERROR] [1562982116.895329988]: Tried to advertise on topic [/msg] with md5sum [34add168574510e6e17f5d23ecc077ef] and datatype [std_msgs/Int64], but the topic is already advertised as md5sum [da5909fbe378aeaf85e547e830cc1bb7] and datatype [std_msgs/Int32]
```

一方、同じtopic名でmsgの型が異なる複数のsubscriberが起動してもエラーメッセージは出ません。しかし、msgの型が違うtopicを受け取ると以下のように表示されます。

```text:エラーメッセージ
[WARN] [1562982934.749605]: Could not process inbound connection: topic types do not match: [std_msgs/Int32] vs. [std_msgs/Int64]{'topic': '/msg', 'tcp_nodelay': '0', 'md5sum': 'da5909fbe378aeaf85e547e830cc1bb7', 'type': 'std_msgs/Int32', 'callerid': '/talker'}
```

## launchで指定のpkg or nodeが存在しない

```text:エラーメッセージ（packageが存在しない）
ERROR: cannot launch node of type [package_a1/main]: package_A1
ROS path [0]=/opt/ros/kinetic/share/ros
ROS path [1]=/home/ubuntu/catkin_ws/src
ROS path [2]=/opt/ros/kinetic/share
```

```text:エラーメッセージ（nodeが存在しない）
ERROR: cannot launch node of type [package_a/main1]: can't locate node [main1] in package [package_a]
```

## launchでxmlの構造がおかしい
大体は空要素タグ`<name />`を書こうとして最後のスラッシュを忘れているパターンです。

```text:エラーメッセージ
Invalid roslaunch XML syntax: mismatched tag: line 4, column 2
The traceback for the exception was written to the log file
```

## 存在しない argを指定している
test.launchにはtest2というargは存在しないのに、それを指定しています。

```text:エラーメッセージ
unused args [test2] for include of [/home/ubuntu/catkin_ws/src/package_A/launch/test.launch]
The traceback for the exception was written to the log file
```

```xml:問題の部分
<!-- START wrap.launch -->
<launch>
  <include file="$(find package_A)/launch/test.launch">
    <arg name="test2" value="b" />
  </include>
</launch>
<!-- END wrap.launch -->

<!-- START test.launch -->
<launch>
  <arg name="test" default="a" />
  <node name="main" pkg="package_A" type="main">
  </node>
</launch>
<!-- END test.launch -->
```

## urdfのタグが閉じていない
xmlの構造のおかしいurdfをロードするといろいろと問題が起きます。robot_state_publisherが以下のようなエラーを出して落ちます。

```
[ERROR] [1541421124.317840763]: Error reading end tag.
[robot_state_publisher-5] process has died
```

## ros::init()を実行する前にNodeHandleの操作をした。
普通はしないのですが、例えば以下のようにtf::TransformListenerをグローバルに宣言をすると問題を起こします。コンパイルは通りますが、実行時にエラーになります。

```text:エラーメッセージ
[FATAL] [1562935209.518769274]: You must call ros::init() before creating the first NodeHandle
```

```c++:原因のソース
#include <ros/ros.h>
#include <tf/transform_listener.h>
tf::TransformListener listener;
int main(int argc, char **argv){
  ros::init(argc, argv, "talker");
  return 0;
}
```


<!--
## pythonノードで実行権限がない
## pythonノードでライブラリに正しくリンクできてない
## dynamic_reconfigureで実行権限がない
## 同じ名前のnodeが複数ある
## pluginが存在しない

# rviz & tf編
## fixed worldが不正
## tfの時間がバラバラ

# gazebo編
## gazebo worldのパスが通っていない
## gazebo modelのパスが通っていない
## use_sim_timeが設定されていない

# 複数マシン系
## hostsが設定されていない
## 名前で解決ができない
## ROS_IPが設定できていない

-->

# 目次ページへのリンク
[ROS講座の目次へのリンク](https://qiita.com/srs/items/5f44440afea0eb616b4a)