## page was renamed from ja/rosserial_arduino/jaTutorials/Push%20Button
## page was renamed from rosserial_arduino_demos/Tutorials/Push Button
## page was renamed from rosserial_arduino_tutorials/Tutorials/Push Button
## For instruction on writing tutorials
## http://www.ros.org/wiki/WritingTutorials
####################################
##FILL ME IN
####################################
## for a custom note with links:
## note =
## for the canned note of "This tutorial assumes that you have completed the previous tutorials:" just add the links
## note.0=
## descriptive title for the tutorial
## title = Push Button
## multi-line description to be displayed in search
## description = Monitor a push button and publish its state in ROS
## the next tutorial description (optional)
## next =
## links to next tutorial (optional)
## next.0.link=
## next.1.link=
## what level user is this tutorial for
## level= BeginnerCategory
## keywords =
####################################
<<IncludeCSTemplate(TutorialCSHeaderTemplate)>>

<<TableOfContents(4)>>
このチュートリアルはボタンを押すというROSの中に統合したいもっとも簡単でもっとも一般的なハードウェアについて書いていきます。(ロボットに次のタスクをさせるための命令や、箱が空いていることを知らせたり、関節の限界を知ってモータが動くのを止める重要なセーフティーの代わりにボタンや入力デバイスについてです。)

このチュートリアルでは、通常はoffになっている7番ピンの状態を監視するrisserial_arduinoのnodeを書きます。ボタンの状態が変わったときに"pushed"というtopicにbooleanのメッセージをパブリッシュします。

== ハードウェア ==
このチュートリアルでは、[[http://www.sparkfun.com/products/9950|Arduino]]通常はオフになっているなんらかのモメンタリースイッチか押しボタンが必要です。このの[[http://www.sparkfun.com/products/9414|microswitch from Sparkfun]]を選ぶとよいでしょう。

{{attachment:button_hardware.png}}

ハードウェアデザインを使うのに慣れている人たちは、スイッチの入力にプルアップレジスタがないことに気づくでしょう。これはArduinoはプルアップレジスタで作られてるからです。7ピンはボタンが押されてGNDと接続するまでhighになっています。

== コード ==
プログラムのコードは以下のようになっています。直接以下のコードをArudino IDEの新しいスケッチにコピーしてください。
{{{
#!cplusplus block=button
/* 
 * Button Example for Rosserial
 */

#include <ros.h>
#include <std_msgs/Bool.h>


ros::NodeHandle nh;

std_msgs::Bool pushed_msg;
ros::Publisher pub_button("pushed", &pushed_msg);

const int button_pin = 7;
const int led_pin = 13;

bool last_reading;
long last_debounce_time=0;
long debounce_delay=50;
bool published = true;

void setup()
{
  nh.initNode();
  nh.advertise(pub_button);
  
  //initialize an LED output pin 
  //and a input pin for our push button
  pinMode(led_pin, OUTPUT);
  pinMode(button_pin, INPUT);
  
  //Enable the pullup resistor on the button
  digitalWrite(button_pin, HIGH);
  
  //The button is a normally button
  last_reading = ! digitalRead(button_pin);
 
}

void loop()
{
  
  bool reading = ! digitalRead(button_pin);
  
  if (last_reading!= reading){
      last_debounce_time = millis();
      published = false;
  }
  
  //if the button value has not changed during the debounce delay
  // we know it is stable
  if ( !published && (millis() - last_debounce_time)  > debounce_delay) {
    digitalWrite(led_pin, reading);
    pushed_msg.data = reading;
    pub_button.publish(&pushed_msg);
    published = true;
  }

  last_reading = reading;
  
  nh.spinOnce();
}
}}}

このコードはrosserial_arduinoが使われる典型的な例です。rosserialオブジェクトはグローバルで宣言されてます。

<<CodeRef(button, 9,12)>>
setup関数の中で初期化をします。

<<CodeRef(button,24,25)>>
そしたらloop関数の中でボタンの状態が変わったときにパブリッシュが働きます。
<<CodeRef(button, 55,55)>>


=== ボタンの状態を監視する ===

このセンサーはボタンの状態についてのメッセージを常に垂れ流し続けるべきではありませんが、ボタンが押されたり離されるときのみパブリッシュされるべきです。この変化を見るには、ボタンの最新の状態を知り、どのぐらいこの状態が有効なのかを知る必要があります。そこで、一度状態が変化したら、センサーはボタンをデバウンスするべきです。十分長い間待っているので、ボタンの値が落ち着き振動してないことがわかります。これは、入力ピンでの電圧が、接触と切断の間にメカ的な接触が上下することになるように、(以下の図で示すように)跳ね回るからです。

{{attachment:debounce.png}}

コードの中で、このデバウンスは起こるところはごくわずかです。まず、ボタンの最新の状態を持っている変数と、読み取りにかかる時間、デバウンスのための遅延時間、パブリッシュされたかを持っとくグローバル変数があります。
<<CodeRef(button,17,20)>>

つぎにsetup関数のなかで、IOとプルアップレジスタのためのArduinoのピンを初期化しました。状態変数も初期化します。
<<CodeRef(button,27,36)>>
最後に、loop関数の中で、コードはどのループのときもボタンの状態を読み、上体が変わってないかを調べ、状態が落ち着いているかパブリッシュされているかを確認します。

== テスト ==

roscoreを立ち上げます。
{{{
roscore
}}}
新しいターミナルで、rosserial_pythonのserial_node.pyを実行します。正しいシリアルポートを使っていることを確かめます。
{{{
rosrun rosserial_python serial_node.py /dev/ttyUSB0
}}}
さて、pushedというtopicのボタンの値を見てみましょう。
{{{
rostopic echo pushed
}}}

## AUTOGENERATED DO NOT DELETE
## TutorialCategory
## FILL IN THE STACK TUTORIAL CATEGORY HERE