概要
クラスのメンバ変数はコンストラクタで初期化することができますが,ROSのメッセージ(例えばgeometry_msgs::Twist
)などは下記のようにすべての変数にアクセスして初期化しなければなりません.
geometry_msgs::Twist twist;
twist.linear.x = 0.0;
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;
通常使用時にはそこまで気にならなかったのですが,この前geometry_msgs::Twist
をconstでクラスメンバ変数として作成しようとしたときに初期化方法がわからなかったので,調べたついでにここにメモします.
環境
- Ubuntu 16.04
- ROS: Kinetic
- C++: C++11以降
- コンパイル時には
CMakeLists.txt
にてC++11がコンパイルできるようにしておく
- コンパイル時には
const宣言されたROSメッセージの初期化方法
残念ながらきれいな初期化方法が見つからなかったので,無理矢理コンストラクタで初期化する方法2つを紹介します.
0. メッセージ内変数をすべて0で初期化したい場合
公式曰く,C++では宣言されたROSメッセージにはデフォルトで0が入るらしいので,小賢しい方法は必要ありません.
1. メンバ変数初期化用の関数を作成
パッと思いついた方法.初期化したいメンバ変数型を返り値とする関数を予め用意しておきます.(@yuki12さんより指摘いただいたので初期化用関数をクラス外に作成)
パッと思いついただけあって,初期化したいメンバ変数の分,初期化用関数が増えていってしまうのが難点.
// geometry_msgs::Twist初期化用関数
geometry_msgs::Twist geoTwistInit (const std::vector<double>& c_twist)
{
geometry_msgs::Twist twist;
twist.linear.x = c_twist[0]; twist.linear.y = c_twist[1]; twist.linear.z = c_twist[2];
twist.angular.x = c_twist[3]; twist.angular.y = c_twist[4]; twist.angular.z = c_twist[5];
return twist;
}
class Hoge
{
private:
const geometry_msgs::Twist cmd_vel_;
public:
Hoge(void):
cmd_vel_(geoTwistInit(std::vector(1.0, 1.0, 1.0, 2.0, 2.0, 2.0)))
{
std::printf("cmd_vel: %f, %f, %f, %f, %f, %f", cmd_vel_.linear.x, cmd_vel_.linear.y, cmd_vel_.linear.z, cmd_vel_.angular.x, cmd_vel_.angular.y, cmd_vel_.angular.x);
}
};
int main (void)
{
Hoge hoge;
return 0;
}
出力
cmd_vel: 1.0, 1.0, 1.0, 2.0, 2.0, 2.0
2.ラムダ式を使う方法
他に方法がないか調べたところ,ROSに限らずコンストラクタが設定されていない型の初期化方法としてラムダ式を使う方法を発見(参考).
class Hoge
{
private:
const geometry_msgs::Twist cmd_vel_;
public:
Hoge(void):
cmd_vel_( []()->geometry_msgs::Twist{geometry_msgs::Twist twist;
twist.linear.x=1.0; twist.linear.y=1.0; twist.linear.z=1.0;
twist.angular.x=2.0; twist.angular.y=2.0; twist.angular.z=2.0;
return twist;}() )
{
std::printf("cmd_vel: %f, %f, %f, %f, %f, %f", cmd_vel_.linear.x, cmd_vel_.linear.y, cmd_vel_.linear.z, cmd_vel_.angular.x, cmd_vel_.angular.y, cmd_vel_.angular.x);
}
};
int main (void)
{
Hoge hoge;
return 0;
}
出力
cmd_vel: 1.0, 1.0, 1.0, 2.0, 2.0, 2.0
キモはラムダ式の最後に()
をつけることらしい.
まとめ
紹介した2つの方法はどちらもあまりきれいではありませんが,力業で解決できることがわかってよかったです.