ラズパイでジャイロセンサの値を取り込んでcsvにする

## Pythonでロボットを作ってみたい
高専に在学していたときにRaspberry piとArduinoを触る機会があったので、改めて使ってみたいと最近思いました。

ロボット制作でよく使うジャイロセンサを使ってみました:robot:

比較的値段も安価だったので
・Raspberry Pi 3 Model B (Ubuntu MATE 16.04.2 LTS)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2958142/29843331-66bb-cdf8-3cb4-da052a6dc926.png)


・Arduino 9axis motion shield (Arduino uno)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2958142/e236a90f-ccfe-f947-b06c-083db2121672.png)

を用意しました。

前よりも少し値上がりしている印象です。。

### 構成イメージ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2958142/eec21f16-b849-160c-842d-7915724f4040.png)

### プログラムコード

```python:gyro.py
#! /usr/bin/env python

# 必要なライブラリをインポート
import serial  # シリアル通信ライブラリ
import csv     # CSVファイルの操作用ライブラリ
import time    # 時間関連の操作ライブラリ
import signal  # シグナル処理関連のライブラリ
import datetime  # 日付と時刻に関連する操作ライブラリ
import rospy   # ROSのPythonラッパー
from robot.msg import Angle  # カスタムROSメッセージ型のインポート


# ROSノードを初期化
rospy.init_node('GYRO_DATE_OUT')
pub = rospy.Publisher('GYRO', Angle, queue_size=100)

# シリアル通信の設定
dev = '/dev/ttyACM0'  # シリアルポートのデバイスパス
rate = 115200         # ボーレート

# シリアル通信の初期化
serial_port = serial.Serial(dev, rate)
msg_angle = Angle()
rate = rospy.Rate(50)

# CSVファイルの初期化
timenow = datetime.datetime.today()  # CSVファイルを開いた時刻を取得
csv_name = str(timenow) + '_gyro.csv'  # CSVファイル名
f = open(csv_name, 'a')  # CSVファイルを開く
writer = csv.writer(f, lineterminator='\n')  # CSVライターの初期化
writer.writerow(['raspi_time', 'arduino_time', 'yaw', 'pitch', 'roll'])  # CSVファイルのヘッダ行

# Arduinoからデータを受信
while True:  # 無限ループ
    try:
        code = serial_port.readline()  # Arduinoからデータを受信
        raspi_time = datetime.datetime.today()  # 現在の時刻を取得
        angle = code.split(',')  # データをカンマ(,)で分割

        # もし最初のデータが'gyro'で始まるならデータを保存
        if angle[0] == 'gyro':
            msg_angle.raspi_get_time = str(raspi_time)
            get_time = str(angle[1])
            msg_angle.angle_get_time = get_time
            yaw = str(angle[2])
            msg_angle.yaw = yaw
            roll = str(angle[3])
            msg_angle.roll = roll
            pitch = str(angle[4])
            msg_angle.pitch = pitch

            pub.publish(msg_angle)  # 受信したデータをROSトピックにパブリッシュ

            writer.writerow([raspi_time, angle[1], angle[2], angle[4], angle[3])  # データをCSVファイルに保存

            rate.sleep()  # ループの頻度を制御
        else:
            print('can not get')
            print(datetime.datetime.today())

    except rospy.ROSInterruptException:
        f.close()  # ファイルを閉じる
        print('gyro_down')
        pass
```


### 使用しているモジュールについて
なんとなく使っていたので、各モジュールについて少し調べてみました。

1.`import serial`: 
`serial`は、Pythonのシリアル通信を制御するためのモジュールです。シリアル通信は、マイクロコントローラやセンサーとのデータ通信に使用されていて、デバイスとコンピュータ間でシリアル通信プロトコルを介してデータを送受信することができます。

2.`import csv`: 
`csv`モジュールは、Comma-Separated Values（CSV）形式のデータを読み書きするためのツールです。CSVはテキストファイル形式で、データを行と列に整理するために使用されています。

3.`import time`: 
`time`モジュールは時間関連の操作をサポートしています。時間の取得、待機、スリープなどの操作が含まれます。

4.`import datetime`: 
`datetime`モジュールは、日付と時刻に関する操作をサポートします。現在の日付や時刻を取得するために使用されています。これはtimeと扱いはほとんど同じです。

5.`import rospy`: 
ROS（Robot Operating System）のPythonラッパーで、ロボットアプリケーションを開発するためのフレームワークです。ROSを使用すると、ロボット制御やセンサーデータの処理が容易に行うことができます。

### 出力結果(csv)
| raspi_time | arduino_time | yaw | pitch | roll |
|------------|--------------|-----|-------|------|
| 02:31.5    | 326724       | 0   | -1.56 | -4.25 |
| 02:31.5    | 326664       | 0   | -1.56 | -4.25 |
| 02:31.5    | 326684       | 0   | -1.56 | -4.25 |
| 02:31.6    | 326704       | 0   | -1.56 | -4.25 |
| 02:31.6    | 326724       | 0   | -1.56 | -4.25 |
| 02:31.6    | 326664       | 0   | -1.56 | -4.25 |
| 02:31.6    | 326684       | 0   | -1.56 | -4.25 |
| 02:31.6    | 326704       | 0   | -1.56 | -4.25 |
| 02:31.7    | 326724       | 0   | -1.56 | -4.25 |
| 02:33.7    | 1564         | 360 | -1.5  | -4.56 |
| 02:33.7    | 1584         | 359.94 | -1.5 | -4.5 |
| 02:33.7    | 1604         | 359.94 | -1.5 | -4.5 |
| 02:33.7    | 1624         | 359.94 | -1.5 | -4.5 |
| 02:33.7    | 1644         | 359.94 | -1.5 | -4.5 |
| 02:33.8    | 1664         | 359.94 | -1.5 | -4.5 |
| 02:33.8    | 1684         | 359.94 | -1.5 | -4.5 |
| 02:33.8    | 1704         | 359.94 | -1.5 | -4.5 |
| 02:33.8    | 1724         | 359.94 | -1.5 | -4.5 |
| 02:33.8    | 1744         | 359.94 | -1.5 | -4.5 |

あまりジャイロセンサーを動かさなかったので、yaw・pitch・rollに変化はありませんがうまく出力されていることが確認できました。