九州工業大学 CIR-KIT Blog

九工大自律移動ロボット製作プロジェクトCIR-KITの技術系ブログ

ジョイスティックで4つのLEDをつける(Arduino&ROS)

 ジョイスティックで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 Install済み CIR-KITメンバーが必ずすべきこと
Arduino Install済み ‘sudo apt-get install Arduino’
rosserial Install済み ArduinoをROSで動かす
joystick_drivers Install済み ROS Wiki

はじめに

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パッケージの中で作業します.

アダプターノード作成

1
2
mkdir src
cd src

この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 コマンドでトピックを確認することで問題を特定しやすくなります.

補足など

後ほどコメントや修正,解説などを加えると思います.