# 暑假大爆發 [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 ``` ![](https://i.imgur.com/rB1KsP7.png) / - 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() ``` ![](https://i.imgur.com/V79gD1x.png) ### 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)的頻率公式有錯 **正確:** ![](https://i.imgur.com/GEr4RQJ.png) 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 泥庫