雷

  • 首页

  • 关于

  • 标签

  • 分类

  • 归档

  • 站点地图

端到端自动驾驶

发表于 2020-02-04 分类于 自动驾驶

训练和推理部分的代码使用tensorflow实现,环境安装请参考网络,这里主要对以下几点进行讲解。

  • 提供完整的实现代码
  • 对核心代码流程进行讲解
  • 主要功能模块讲解

代码所在文件夹为selfDriveCarMD

drive.py 实现了采集数据和运行模型功能

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93

# 通过以下命令交互帮助可知:
# python drive.py --js 为采集数据的命令
# python drive.py --model=./models/xxx.h5 为运行模型命令
"""
Usage:
drive.py [--model=<model>] [--js]

Options:
-h --help Show this screen.
--js Use physical joystick.
"""

# 引入opencv包
import cv2
# 引入CarManager包,此包用来管理所有功能模块的业务逻辑
from processThread.CarManage import CarManager
# 引入terminalPrint包,此包实现了终端个性化打印功能,防止显示数据刷屏
from tools.terminalPrint import TerminPrint
# 引入命令行交互解析工具包
from docopt import docopt
# 引入树莓派摄像头驱动包,此例被禁用
# from tools.nanoTool import CSICamera

# 定义串口名称和波特率,为了控制实体小车用,所以与实体车的通讯接口为串口
serialTTY='/dev/ttyUSB0'
bandRate=115200

# 定义usb摄像头
cap = cv2.VideoCapture(0)

# 主程序入口

if __name__ == "__main__":

# 获得命令行输入参数
args = docopt(__doc__)
# 模型地址名称
modelDirName=args['--model']
# 获取遥控参数
man=args['--js']

driveMode='man'

# 如果有模型地址设置运行模型
if(modelDirName is not None):
driveMode=modelDirName

# 初始化车管理模块
carMan=CarManager(dev_fn=serialTTY, bandRate=bandRate, driveMode=driveMode)

# 初始化终端显示风格
TerminPrint.levelModePrint("主进程: {}".format(os.getpid()), level='info')

# 启动串口进程
carMan.startSerialProcess()
# 启动摇杆进程
carMan.startjoyStickProess()
# 启动数据存储线程
carMan.startDataStoreThread(fps=10)
# 启动网页图传线程
carMan.startWebCameraConServerThread()

# 打印用户自定义信息,防止刷屏
TerminPrint.levelModePrint("所有进程线程完成执行", level='info')
TerminPrint.levelModePrint('道 路 千 万 条', level='warn')
TerminPrint.levelModePrint('安 全 第 一 条', level='warn')
TerminPrint.levelModePrint('行 车 不 规 范', level='warn')
TerminPrint.levelModePrint('亲 人 两 行 泪', level='warn')

while(True): # 主进程运行
try:
# 摄像头剪裁, 最终尺寸与神经网络输入一致
ret, img = cap.read()
if not ret: break
img=cv2.resize(img, (224, 168))
img=img[28:140,:] # 最终目的是把输入图片等比例切片成尺寸为(224x112)的图象
img=cv2.flip(img, 1) # 反转图象
# img=cv2.flip(img, 0)

# img=roboCamera.getFrame()
# img=img[7:119,:] # slicing to img size (224x112)
# img=cv2.flip(img, 1) # flipped Horizontally

# 根据车管理类决定执行 [遥控采集] 或者 [推理模型]
carMan.controlCar(img)
# carMan.controlCar(img, wifiCamera=False)
cv2.imshow('camera', img)
cv2.waitKey(1)
except KeyboardInterrupt:
print('close camera')
cap.release()
# roboCamera.cap.release()

train.py 实现了训练模型功能

1
2

待补充...

modelTest.py 用于调试测试用,当训练完模型后可以用测试模型效果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47

# 同样加载所需依赖包
import cv2
from processThread.CarManage import CarManager
from tools.terminalPrint import TerminPrint
import time
import os
import glob
import json

# 初始化车管理模块和加载测试模型
carMan=CarManager(dev_fn=None, driveMode='models/mecanum.h5')

# 启动网页图传线程
carMan.startWebCameraConServerThread()

# 读取数据集文件夹,加载图片并排序
imageWidth=224
imageHeight=112
middleWidth=int(imageWidth/2)
datePath = 'dataMecanum'
fileNames = glob.glob(os.path.join(datePath, '*.jpg'))
fileNames.sort()

# 遍历图片,预测并显示角度
for name in fileNames:
img= cv2.imread(name)

numJpg=name.split('_')[0].split('/')[1]
recodeFile='record_'+numJpg+'.json'
fileData = open(datePath+'/'+recodeFile, "rb")
fileJson = json.load(fileData)
angle = fileJson['user/angle']
# throttle = fileJson['user/throttle']
# print(angle)
x=int(angle*middleWidth+middleWidth)
cv2.line(img, (middleWidth, imageHeight), (x, 0), (0,255,0), 2)

predictAngle, predictThrottle=carMan.webControThread.drive_model.predict_image(img)

predictX=int(predictAngle*middleWidth+middleWidth)
cv2.line(img, (middleWidth, imageHeight), (predictX, 0), (255,0,0), 2)

cv2.imshow('camera', img)
time.sleep(0.2)

cv2.waitKey(1)

在baseModels文件夹里定义的是模型结构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28

# default_model函数中可以看到网络定义结构,训练参数和梯度下降方法

def default_model():
img_in = Input(shape=(112, 224, 3),name='img_in')
x = img_in
x = Convolution2D(24, (5, 5), strides=(2, 2),activation='relu')(x)
x = Convolution2D(32, (3, 3), strides=(2, 2),padding='same',activation='relu')(x)
x = Convolution2D(64, (3, 3), strides=(2, 2),padding='same',activation='relu')(x)
x = Convolution2D(64, (3, 3), strides=(1, 1),padding='same',activation='relu')(x)
x = Convolution2D(64, (3, 3), strides=(2, 2),padding='same',activation='relu')(x)
x = Convolution2D(64, (3, 3), strides=(1, 1),padding='same',activation='relu')(x)
x = Convolution2D(128, (3, 3), strides=(2, 2), padding='same',activation='relu')(x)
x = Convolution2D(128, (3, 3), strides=(1, 1), padding='same',activation='relu')(x)
x = Flatten(name='flattened')(x)
x = Dense(100, activation='relu')(x)
x = Dropout(.1)(x)
x = Dense(50, activation='relu')(x)
x = Dropout(.1)(x)
angle_out = Dense(15, activation='softmax', name='angle_out')(x)
throttle_out = Dense(1, activation='relu', name='throttle_out')(x)
model = Model(inputs=[img_in], outputs=[angle_out, throttle_out])
model.compile(optimizer='adam',
loss={'angle_out': 'categorical_crossentropy',
'throttle_out': 'mean_absolute_error'},
loss_weights={'angle_out': 0.9, 'throttle_out': .01})

return model

models文件夹里放的是训练好的模型

nanoSDK文件夹里代码很多,主要用来实现数据和通讯相关的功能

  • dataBuild.py 用来构建数据集
  • dataStore.py 用来实现数据存储
  • mecanumJoyStick.py 用来实现遥控器数据接收功能
  • pymqtt.py 用来实现手机网页端与车之间的通讯
  • webController.py 用来实现手机网页端的构建

processThread文件夹里的代码用来实现多线程功能

  • CarManage.py 实现车线程管理总类
  • dataStoreThread.py 定义数据采集存储线程类
  • joyStickProcess.py 定义遥控器接收数据进程类
  • SerialProcess.py 定义串口通讯进程类
  • webControllerThread.py 定义网页图传控制传输线程类

tools文件夹定义相关工具类

  • nanoTool.py 里边有树莓派csi摄像头驱动
  • terminalPrint.py 实现终端自定义显示类

完整代码: 待更新…

# opencv # CNN
qt,NCNN,Darknet,多线程
  • 文章目录
  • 站点概览
ray

ray

17 日志
23 分类
18 标签
RSS
  1. 1. 训练和推理部分的代码使用tensorflow实现,环境安装请参考网络,这里主要对以下几点进行讲解。
  2. 2. 代码所在文件夹为selfDriveCarMD
    1. 2.1. drive.py 实现了采集数据和运行模型功能
    2. 2.2. train.py 实现了训练模型功能
    3. 2.3. modelTest.py 用于调试测试用,当训练完模型后可以用测试模型效果
    4. 2.4. 在baseModels文件夹里定义的是模型结构
    5. 2.5. models文件夹里放的是训练好的模型
    6. 2.6. nanoSDK文件夹里代码很多,主要用来实现数据和通讯相关的功能
    7. 2.7. processThread文件夹里的代码用来实现多线程功能
    8. 2.8. tools文件夹定义相关工具类
    9. 2.9. 完整代码: 待更新…
0%
© 2020 ray
由 Hexo 强力驱动 v3.9.0
|
主题 – NexT.Pisces v7.3.0