# ROS
#### 組員: A1105129 吳祥毅 M1115114 楊皓翔
#### 指導老師:林宏益
---
### 一、實驗目的
將軟硬體整合,實現ROS的Topic功能
### 二、實驗原理
利用樹莓派控制L298n用以掌控兩側馬達轉速,並在樹莓派中使用ROS內Topic功能控制車輛
### 三、實驗材料
1. Raspberry Pi 1
2. L298n
3. Dc-Dc converter
4. 小車
### 四、實驗步驟&結果
1. 將車子本體組裝完畢

2. 一側馬達的Vcc&GND,應放置在一起,再放入L298n的Channel
:::info
需先確認馬達轉向相同,才能將一側馬達的線相互接起來
:::
3. 利用`pinout`或說明書查看腳位,將L298n與樹莓派相互連接
:::warning
總共7個腳位,in1,in2,in3,in4,en1,en2,GND
:::

4. 開始撰寫Topic內的Pub&Sub
:::success
> 我是先撰寫好GPIO程式並測試過後,再轉移到robot_sub.py裡面
**robot_pub.py**
``` pyhton=
#!/usr/bin/python3
import rospy
from std_msgs.msg import String
rospy.init_node('robot_command_publisher')
pub = rospy.Publisher('/robot_control', String, queue_size=10)
rate = rospy.Rate(10)
while not rospy.is_shutdown():
command = input("Enter command (forward/backward/right_turn/left_turn/stop): ")
pub.publish(command)
rate.sleep()
```
**robot_sub.py**
``` pyhton=
#!/usr/bin/python3
import RPi.GPIO as GPIO
import rospy
from time import sleep
from std_msgs.msg import String
in1 = 17
in2 = 18
in3 = 22
in4 = 23
en_left = 27
en_right = 24
GPIO.setmode(GPIO.BCM)
GPIO.setup(in1, GPIO.OUT)
GPIO.setup(in2, GPIO.OUT)
GPIO.setup(in3, GPIO.OUT)
GPIO.setup(in4, GPIO.OUT)
GPIO.setup(en_left , GPIO.OUT)
GPIO.setup(en_right, GPIO.OUT)
left_pwm = GPIO.PWM(en_left , 1000)
left_pwm.start(40)
right_pwm = GPIO.PWM(en_right, 1000)
right_pwm.start(40)
def stop():
GPIO.output(in1, GPIO.LOW)
GPIO.output(in2, GPIO.LOW)
GPIO.output(in3, GPIO.LOW)
GPIO.output(in4, GPIO.LOW)
def left_for():
GPIO.output(in1, GPIO.LOW)
GPIO.output(in2, GPIO.HIGH)
def right_for():
GPIO.output(in3, GPIO.LOW)
GPIO.output(in4, GPIO.HIGH)
def left_back():
GPIO.output(in1, GPIO.HIGH)
GPIO.output(in2, GPIO.LOW)
def right_back():
GPIO.output(in3, GPIO.HIGH)
GPIO.output(in4, GPIO.LOW)
def control_robot(data):
command = data.data
if command == 'stop' or command == 's':
stop()
elif command == 'forward' or command == 'f' :
left_for()
right_for()
sleep(2)
elif command == 'backward' or command == 'b':
left_back()
right_back()
sleep(2)
elif command == 'right_turn' or command == 'r':
left_for()
right_back()
sleep(2)
elif command == 'left_turn' or command == 'l':
left_back()
right_for()
sleep(2)
stop()
rospy.init_node('robot_controller')
rospy.Subscriber('/robot_control', String, control_robot)
try:
rospy.spin()
except KeyboardInterrupt:
left_pwm.stop()
right_pwm.stop()
GPIO.cleanup()
```
:::
5. 在package內的CMakelists.txt,新增以下指令
:::danger
要放在CMakelists.txt的最後面,因為CMake有優先順序問題
:::
```
catkin_install_python(PROGRAMS
scripts/publisher.py
scripts/subscriber.py
DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
)
```
6. 回到workspace進行編譯,`catkin_make`,便會開始進行編譯

7. 編譯好後,輸入`roscore &`,使其在背景執行
8. 開啟`tmux`並使用`Crtl+b %`開多個視窗以利操作,接輸入`source devel/setup.bash` ,用以建立環境
9. 分別在兩個視窗打開`rosrun robot_control robot_sub.py` `rosrun robot_controlrobot_pub.py`,並執行對應指令,便可實現ROS Topic的功能

11. 皆大歡喜 :+1:
### 五、實驗討論&心得
雖然一開始拿到散亂的零件,有種無從下手的感覺,但隨著把車體構建出來,並可以實際運作,依然是成就感滿滿。透過自己動手組裝,更了解到線路的走線與零件的擺放都是大學問。一直在(動手做-面臨問題-解決問題)中循環,也學會從挫敗中學習,像是CMakelist的優先順序,或是編譯問題,都是一次次的試錯中學習,面對不足並彌補不足。 :+1:
### 六、參考文獻
:::danger
* 參考文獻 : [助教的HackMD](https://hackmd.io/@neko-yoru/rJrW8nbkp) :100: / [ChatGPT](https://chat.openai.com) :+1:
:::
:::info
* 編輯人員 :[name=吳祥毅]
:::