# 暑假大爆發
[TOC]
## 8/12
1. 安裝Jetpcak 4.2 (opencv 3.3.1, Cuda 10.0)
2. 有door.cfg 缺對應的 weights **使用door.yaml即可**
## 8/13
1. DVL 界面 work (下載官網Nortek Discover) [Link](https://www.nortekgroup.com/software?i)
4. ZED SDK and ZED ros wrapper
5. 用Arduino讀到MPU9250 data [Ref](https://hackmd.io/Wth1-ZdVROSO5xjWDoEjEA#Install-MPU9250-Arduino-LIbrary)
6. 讀PID
-----
- 子昊玩方向盤(駕訓班第一天)
- 昀洛畢業證書
- 水聽桶子換水
- **生智學會吹口哨**
-----
Arduino code
``` arduino=
// https://github.com/hideakitai/MPU9250
#include "MPU9250.h"
MPU9250 mpu;
struct Imu
{
float ax, ay, az;
float gx, gy, gz;
float mx, my, mz;
float roll, yaw, pitch;
};
void setup()
{
Serial.begin(9600);
Wire.begin();
delay(2000);
mpu.setup();
}
void loop()
{
static uint32_t prev_ms = millis();
if ((millis() - prev_ms) > 90) // 0.1s
{
mpu.update();
// mpu.print();
// Direct use write() to sedn buffer data
Imu data = {mpu.getAcc(0), mpu.getAcc(1), mpu.getAcc(2),
mpu.getGyro(0), mpu.getGyro(1), mpu.getGyro(2),
mpu.getMag(0), mpu.getMag(1), mpu.getMag(2),
mpu.getRoll(), mpu.getYaw(), mpu.getPitch()};
Serial.write((byte*)&data, sizeof(data));
Serial.write(10);
// Could use print() & println() to sedn over String
/*
Serial.print(mpu.getAcc(0));
Serial.print(" ");
Serial.print(mpu.getAcc(1));
Serial.println();
*/
prev_ms = millis();
}
}
```
用 Pyserial 在TX2讀出
```python=
#!/usr/bin/env python3
import serial
from struct import *
# import rospy
# from std_msgs.msg import String
# from std_msgs.msg import Float32
# from sensor_msgs.msg import Imu
port = '/dev/ttyACM0'
arduino = serial.Serial(port, 9600, timeout=1)
if not arduino.is_open:
arduino.open()
a = 1
# for i in range(30):
# data_raw = arduino.readline()
while(arduino.is_open):
a += 1
data_raw = arduino.readline()
# data = tuple()
try:
data = unpack('ffffffffffffc', data_raw)
print(a, data)
except Exception as e:
print('length: '+ str(len(data_raw)))
print(e)
'''
readline() until asscii 10
Serial.write(10)
'''
# print(a, data_raw)
```
## 8/14
1. 發現tx2開發板不支援PWM
## 8/25
1. 整理 github Controller repo 的 branch
2. 測試同時兩顆馬達的運轉狀況 -> 良好
3. **要確保不會短路**
4. 測試 mpu9250 的 PID code
## 8/26
### 育騰大爆發
```python=
import cv2
import numpy as np
from matplotlib.pyplot import imshow
from matplotlib import pyplot as plt
from scipy.stats import linregress
import matplotlib.pyplot as plt
%matplotlib inline
img = cv2.imread('floor.jpg')
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
bw = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_MEAN_C, \
cv2.THRESH_BINARY, 15, -2)
kernel_size = 5
blur_gray = cv2.GaussianBlur(gray,(kernel_size, kernel_size),0)
low_threshold = 20
high_threshold = 50
edges = cv2.Canny(blur_gray, low_threshold, high_threshold)
rho = 5 # distance resolution in pixels of the Hough grid
theta = np.pi / 180 # angular resolution in radians of the Hough grid
threshold = 100 # minimum number of votes (intersections in Hough grid cell)
min_line_length = 25 # minimum number of pixels making up a line
max_line_gap = 10 # maximum gap in pixels between connectable line segments
line_image = np.copy(img) * 0 # creating a blank to draw lines on
lines = []
# Run Hough on edge detected image
# Output "lines" is an array containing endpoints of detected line segments
lines = cv2.HoughLinesP(edges, rho, theta, threshold, np.array([]),
min_line_length, max_line_gap)
count=0
for line in lines:
count+=1
for x1,y1,x2,y2 in line:
cv2.line(line_image,(x1,y1),(x2,y2),(255,0,0),5)
# Draw the lines on the image
lines_edges = cv2.addWeighted(img, 0.8, line_image, 1, 0)
# x1 x2 y1 y2 can form a line
lines = lines.reshape(count,4)
slope = []
for i in range(count):
x_coordinate = []
y_coordinate = []
for j in range(4):
if j%2:
y_coordinate.append(lines[i][j]) #y coordinate for y1 y2
else:
x_coordinate.append(lines[i][j]) #x coordinate for x1 x2
#do a linear regression to get slope of line
result = linregress(x_coordinate, y_coordinate)
# got the degree by slope
result = np.degrees(np.arctan(result[0]))
# turn two slope into the same theta
if abs(result)>45:
slope.append(abs(result))
else:
slope.append(90-abs(result))
#delete the nan
slope = [slope for slope in slope if str(slope) != 'nan']
#average all possible slope
if len(slope) >0:
s = sum(slope)/len(slope)
print(s)
plt.imshow(lines_edges)
plt.show
```

/
- yaw 最終版本:超過45度就不準了
```python=
import numpy as np
import cv2
import time
from matplotlib.pyplot import imshow
from matplotlib import pyplot as plt
from scipy.stats import linregress
import matplotlib.pyplot as plt
from numpy import *
import sys
%matplotlib inline
cap = cv2.VideoCapture(0)
while(True):
#cv2.waitKey(delay_time)
ret, frame = cap.read()
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
bw = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_MEAN_C, \
cv2.THRESH_BINARY, 15, -2)
kernel_size = 5
blur_gray = cv2.GaussianBlur(gray,(kernel_size, kernel_size),0)
low_threshold = 20
high_threshold = 50
edges = cv2.Canny(blur_gray, low_threshold, high_threshold)
rho = 6 # distance resolution in pixels of the Hough grid
theta = np.pi / 60 # angular resolution in radians of the Hough grid
threshold = 400 # minimum number of votes (intersections in Hough grid cell)
min_line_length = 50 # minimum number of pixels making up a line
max_line_gap = 25 # maximum gap in pixels between connectable line segments
line_image = np.copy(blur_gray) * 0 # creating a blank to draw lines on
lines = []
# Run Hough on edge detected image
# Output "lines" is an array containing endpoints of detected line segments
lines = cv2.HoughLinesP(edges, rho, theta, threshold, np.array([]),
min_line_length, max_line_gap)
count=0
#print(lines is None)
if lines is None:
continue
#print(lines)
for line in lines:
count+=1
for x1,y1,x2,y2 in line:
cv2.line(line_image,(x1,y1),(x2,y2),(255,0,0),5)
# Draw the lines on the image
lines_edges = cv2.addWeighted(blur_gray, 0.8, line_image, 1, 0)
lines = lines.reshape(count,4)
slope1=[]
slope2=[]
for i in range(count):
x_coordinate = []
y_coordinate = []
for j in range(4):
if j%2:
y_coordinate.append(lines[i][j])
else:
x_coordinate.append(lines[i][j])
result=linregress(x_coordinate,y_coordinate)
result=np.degrees(np.arctan(result[0]))
#print(result)
if result>=0:
slope1.append(result)
else:
slope2.append(result)
slope1=[slope1 for slope1 in slope1 if str(slope1) != 'nan']
slope2=[slope2 for slope2 in slope2 if str(slope2) != 'nan']
#print('slope1=',slope1)
#print('slope2=',slope2)
s1=sum(slope1)/len(slope1)
s2=sum(slope2)/len(slope2)
if len(slope1)>0:
s1=sum(slope1)/len(slope1)
#print('average1=',s1)
if len(slope2)>0:
s2=sum(slope2)/len(slope2)
#print('average2=',s2)
final1=[]
final2=[]
if(s1<45):
final1.append(s1)
for i in range(len(final1)):
final1= [x for x in final1 if x != max]
print('final1=',final1)
if(abs(s2)<45):
final2.append(s2)
for i in range(len(final2)):
final2= [x for x in final2 if x != max]
print('final2=',final2)
#out.write(lines_edges)
cv2.imshow('lines_edges',lines_edges)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
cap.release()
cv2.destroyAllWindows()
sys.exit()
```

### PCA9685
1. 將 motor control 以 array 傳控制訊號 (kgf)
2. 將 motor control node 包成 class [github](https://github.com/NCTU-AUV/Controller/commit/4dddec15b6373e20a370aa9e72643258fcdbd3e3)
3. 利用 pyqtgraph 視覺化 pitch roll
4. 如果要更改 pca9685 的頻率 要先改回睡眠模式 [網站](http://blog.ittraining.com.tw/2015/07/raspberry-pi2-python-i2c-16-pwm-pca9685.html)的頻率公式有錯
**正確:**

5. [相關細節](https://hackmd.io/yRG0nUkNSgiBiFhXCQy25w?both#PyQt-amp-PyQtGraph)
## 9/2
- PID control 可以在螢幕上跑了 泳池來要去調參數
- Yaw 的地板版本完成即時
## 9/3
:::danger
# 水聽大爆發 :+1: :fire: :dancers: :baby:
- 感謝交大第一顏值擔當 aka 水聽組扛壩子 -- 梁育騰
- 直接拿資料成功
- 肉眼可以看出波形前後
- 麥克風2 (Due板A1) 比較強勢
- 大家回去辨識資料看看
- [FFT & Amplifier & Hilbert](https://wizardforcel.gitbooks.io/hyry-studio-scipy/content/20.html)
:::
-------
## 9/4
- FSM 第一版完成
- 壓力計換算測試
## Detail
想說為了排版方便,就把雜亂的東東丟過來
### PyQt & PyQtGraph
1. https://www.learnpyqt.com/courses/graphics-plotting/plotting-pyqtgraph/
2. https://www.cnblogs.com/linyfeng/p/12239856.html
#### 8/26 pid code
https://www-users.cs.york.ac.uk/~mjf/perpetual_pi/Python/pid.py
### xlxs with python
To read T200 data sheet
``` python=
from openpyxl import load_workbook
wb = load_workbook('T200.xlsx')
sheet_16v = wb.get_sheet_by_name('16 V')
# col_force = [col.value for col in sheet_16v['F']]
# for val in col_force:
# print(val, end=', ')
col_signal = [col.value for col in sheet_16v['H']]
for val in col_signal:
print(val, end=', ')
```
#
### 壓力計
``` python=
#include <Wire.h>
#include "MS5837.h"
MS5837 sensor;
void setup() {
Serial.begin(9600);
Serial.println("Starting");
Wire.begin();
sensor.setModel(MS5837::MS5837_30BA);
sensor.setFluidDensity(997); // kg/m^3 (freshwater, 1029 for seawater)
}
void loop() {
sensor.read();
Serial.print(5.26*(sensor.depth()-196)+1.584);
delay(10);
}
```
## 12/6 檢討
1. NUC 試用
2. Rpi 使用PWM __ **(connect arduino*2)**
3. TX2 視覺
### 配重:
1. 把白色板子拔掉
2. 算浮心
3. 想辦法把密度變成0.9
### 購買:
1. 鉛塊
2. 銅柱
3. 穩壓 (switch 和 NUC 和 TX2)
5. 鰭片
6. 散熱膏
7. KillButtom
### 馬達:
1. 重新焊接
### 鏡頭:
1. train 泥庫