ジョイスティックで4つのLEDをつけるbyROS 
概要 
ROSのトピックを利用してArduinoでledをつける.
更に,ROSのjoystick_driversを利用してDualShock3でledを制御する.
検証情報 
日時 
03/09/2015 (Mon)
スペック 
パーツ 
スペック 
 
 
PC 
Panasonic Let’s note CF-LX3TG7TC 
 
Prosessor 
Intel core i7-4500U (1.8GHz) 
 
RAM 
DDR3 SDRAM(PC3-12800) 4GB 
 
OS 
Ubuntu 14.04.2 LTS 64bit 
 
Kernel 
3.13.0-46-generic 
 
ROS 
indigo 1.11.10 
 
Arduino 
Arduino UNO 
 
joystick_drivers 
1.10.0 
 
 
前提条件 
はじめに 
ROSは,ノードの再利用を理念に作成されているため,出力用,入力用,計算用,アダプター用の4種のパッケージを作るべきだと私は考えています.今回は入力をjoystick_driversに任せて,出力パッケージとアダプターパッケージを作成します.
仕様作成 
今回は4つのLEDを十字に配置して,ジョイスティックのアナログパッドを傾けた方向のLEDを光らせます.この時,傾きに合わせて光る強さを変えられるようにします.
出力パッケージ作成 
出力パッケージは,受け取るメッセージ型を定義し,そのメッセージに対する処理をするノードを作成します.今回パッケージ名はlight_fourledsとします.今回はArduinoを使用し,ROSノードは作らないため依存パッケージはありません.
1 
2 
3 
cd  <catkin_ws>/src
catkin_create_pkg light_fourleds
 cd  light_fourleds
 
以後しばらくはlight_fourledsパッケージの中で作業します.
メッセージ作成 
msg定義 
x軸とy軸を考えてそれぞれの強さを受け取るようにするのが良いと考えました.
よってメッセージ型はVector2とします.内容はfloat32 のxとyです.
1 
2 
3 
4 
mkdir -p msg
 cd  msg
echo  "float32 x"  > Vector2.msg
echo  "float32 y"  >> Vector2.msg
 
msg生成 
まずは定義したmsgをmakeします.Arduinoでmsgを利用するには必ず対象のmsgがmakeされていなければなりません.これはros_libとの関係です.
作ったmsgのためにCMakeListsとpackage.xmlを下のように書き換えましょう.
CMakeLists.txt
1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21 
cmake_minimum_required( VERSION 2.8.3) 
 project( light_fourleds) 
 
 # Load catkin and all dependencies required for this package 
find_package( catkin REQUIRED COMPONENTS message_generation) 
 
 ######################## 
## Declare ROS message## 
######################## 
 # Generate messages in the 'msg' folder 
add_message_files( FILES Vector2.msg) 
 
 ## Generate added messages with any dependencies listed here 
generate_messages() 
 
 ################################### 
## catkin specific configuration ## 
################################### 
 catkin_package( CATKIN_DEPENDS message_runtime) 
 
 
package.txt
1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
11 
12 
13 
14 
15 
16 
17 
<package>
   <name>light_fourleds</name>
   <version>0.1.0</version>
   <description>
     This package defines message, and have node of arduino to light
   four leds.
   </description>
   <maintainer email = "yourName@todo.todo" >yourName</maintainer>
   <license>BSD</license>
 
   <buildtool_depend>catkin</buildtool_depend>
 
   <build_depend>message_generation</build_depend>
 
   <run_depend>message_runtime</run_depend>
   <run_depend>rosserial_python</run_depend>
 </package>
 
 
書き終えたらcatkin_make --force-cmakeを実行します.
1 
2 
cd  <catkin_ws>
catkin_make --force-cmake
 
 
Arduinoノード作成 
それでは実際に今作ったmsgを利用して動く出力ノードを作成します.
まずは,新しく作ったmsgを認識させるためにros_libを削除し,再度rosrunでros_libを入れなおします.roscoreを立ち上げるのを忘れないでください.
1 
2 
3 
cd  <sketchbook>/libraries
rm -fr ros_lib
 rosrun rosserial_arduino make_libraries.py
 
 
続いてそのライブラリが使用できるところでArduinoのプログラムを作成します.下のプログラムを作成してください.
1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21 
22 
23 
24 
25 
26 
27 
28 
29 
30 
31 
32 
33 
34 
35 
36 
37 
38 
39 
40 
/**
  * light four leds on arduino
  * @author "yourName" 
  */
 #include <ros.h> 
#include <light_fourleds/Vector2.h> 
#define UP 3 
#define RIGHT 5 
#define DOWN 6 
#define LEFT 9 
unsigned int der[ 4] ; 
 ros::NodeHandle nh; 
 
 void messageCb( const light_fourleds::Vector2&  msg)  { 
   for  ( int i;  i < 4;  i++)  analogWrite( der[ i] , 0) ;  //all cleanup
   if  ( msg.x > 0)  // left
   analogWrite( der[ 3] , 255*msg.x) ; 
   else  if  ( msg.x < 0)  // right
       analogWrite( der[ 1] , -255*msg.x) ; 
   if  ( msg.y > 0)  // up
       analogWrite( der[ 0] , 255*msg.y) ; 
   else  if  ( msg.y < 0)  // down
       analogWrite( der[ 2] , -255*msg.y) ; 
 } 
 ros::Subscriber<light_fourleds::Vector2> sub( "light_fourleds" , & messageCb) ; 
 
 void setup( void)  { 
   der[ 0]  =  UP; 
   der[ 1]  =  RIGHT; 
   der[ 2]  =  DOWN; 
   der[ 3]  =  LEFT; 
   nh.initNode() ; 
   nh.subscribe( sub) ; 
 } 
 void loop( void)  { 
   nh.spinOnce() ; 
   delay( 1) ; 
 } 
 
書き込んだら,Arduinoでビルドして,uploadしてください.
配線 
3,5,6,9pinにLEDをそれぞれつけてください.3を上にして時計回りに配置すると想定された配置となります.
画像は後ほど追加予定です.
ここまでの確認 
これで出力部が作成できたはずです.ROSの強力な特徴として,ノード単位でのテストができる点があるので,早速実行して試してみましょう.
1 
rosrun rosserial_python serial_node.py
 
 
1 
rostopic pub light_fourleds/Vector2 -- 1  0
 
 
左のLED(9pin)が光っていれば成功です.
アダプターパッケージの作成 
アダプターパッケージは出力と入力パッケージのmsgを適切につなぐパッケージです.個人的な命令方法は「出力パッケージ_adapters」です.これは,使いたい入力に対して適宜adapterノードを作成すれば良いと考えているからです.それでは下のコマンドでパッケージを作りましょう.
1 
2 
3 
cd  <catkin_ws>/src
catkin_create_pkg light_fourleds_adapters roscpp light_fourleds joy
 cd  light_fourleds_adapters
 
以後しばらくはlight_fourleds_adaptersパッケージの中で作業します.
アダプターノード作成 
 
このsrcディレクトリにadapt_joy_node.cppを作成し,以下の文を書き込みます.
1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21 
#include "ros/ros.h" 
#include "light_fourleds/Vector2.h" 
#include "sensor_msgs/Joy.h" 
 ros::Publisher pub; 
 
 void joyCb( const sensor_msgs::Joy::ConstPtr&  joy)  { 
   light_fourleds::Vector2 msg; 
   msg.x =  joy->axes[ 0] ; 
   msg.y =  joy->axes[ 1] ; 
   pub.publish( msg) ; 
 } 
 int main( int argc, char **argv)  { 
   ros::init( argc, argv, "adapt_joy_node" ) ; 
   ros::NodeHandle nh; 
   ros::Subscriber sub  =  nh.subscribe( "joy" , 1, joyCb) ; 
   pub  =  nh.advertise<light_fourleds::Vector2>( "light_fourleds" , 1) ; 
   ros::spin() ; 
   return  0; 
 } 
 
書き込んだら,CMakeLists.txtとpackage.xmlを下のように書き換えます.
CMakeLists.txt
1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
11 
12 
cmake_minimum_required( VERSION 2.8.3) 
 project( light_fourleds_adapters) 
 
 set ( CATKIN_DEPS roscpp sensor_msgs) 
set ( ROSDEP_DEPS light_fourleds) 
find_package( catkin REQUIRED COMPONENTS ${ CATKIN_DEPS }  ${ ROSDEP_DEPS } ) 
 catkin_package( CATKIN_DEPENDS ${ CATKIN_DEPS }  ${ ROSDEP_DEPS } ) 
 
 include_directories( ${ catkin_INCLUDE_DIRS } ) 
 
 add_executable( adapt_joy_node src/adapt_joy_node.cpp) 
 target_link_libraries( adapt_joy_node ${ catkin_LIBRARIES } ) 
 
 
package.xml
1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
<package>
   <name>light_fourleds_adapters</name>
   <version>0.1.0</version>
 
   <description>Adapt message to light_fourleds package.</description>
 
   <maintainer email = "yourName@todo.todo" >yourName</maintainer>
   <license>BSD</license>
 
   <buildtool_depend>catkin</buildtool_depend>
 
   <build_depend>light_fourleds</build_depend>
   <build_depend>roscpp</build_depend>
   <build_depend>sensor_msgs</build_depend>
 
   <run_depend>light_fourleds</run_depend>
   <run_depend>roscpp</run_depend>
   <run_depend>sensor_msgs</run_depend>
 </package>
 
 
すべて書き込んだらworkspace直下へ移動してcatkin_makeします.
1 
2 
cd  <catkin_ws>
catkin_make --force-cmake
 
 
makeが通ったら実行してみましょう.USBポートにジョイスティックとArduinoを接続して,以下の行をそれぞれ別のターミナル で実行してください.
1 
2 
3 
4 
roscore
 rosrun joy joy_node
 rosrun light_fourleds_adapters adapt_joy_node
 rosrun rosserial_python serial_node.py _port:= ttyACM0
 
 
Note: Arduinoのbuildとuploadはしましたか? 
Note: rostopic コマンドでトピックを確認することで問題を特定しやすくなります. 
 
補足など 
後ほどコメントや修正,解説などを加えると思います.