class SimplePIController: #定速巡航
# def __init__(self, Kp, Ki):
# self.Kp = Kp
# self.Ki = Ki
# self.set_point = 0.
# self.error = 0.
# self.integral = 0.
#
# def set_desired(self, desired):
# self.set_point = desired
#
# def update(self, measurement):
# # proportional error
# self.error = self.set_point - measurement
#
# # integral error
# self.integral += self.error
# # print(self.integral)
# return self.Kp * self.error + self.Ki * self.integral
#
# controller = SimplePIController(0.1, 0.002)
# set_speed = 9
# controller.set_desired(set_speed)
#
# throttle = controller.update(speed)
'''
# 太原理工大学实训项目-无人驾驶
# 项目:基于深度学习的Udacity无人驾驶系统
# 学号:2018101039
# 班级:信息18-1
# 姓名:张书胜
# '''
# 1、导入第三方库
import os
import socketio # 轻量级web通信架构,基于TCP/IP协议网络通信应用,套接字
from flask import Flask # miro framework,web微型架构、框架,WSGI,web管理系统、路由转接器
import eventlet.wsgi # Web Server Gateway Interface web 服务器网关接口,连接服务器与客户端
# 图像处理库
import cv2,base64 # 对字节数据处理
from io import BytesIO # 从系统导入的输入值 BytesIO:将文件放入内存运行,用到的数据是二进制 ,StringIO参数时string数据
from PIL import Image # 特定格式打开图片
import numpy as np # 对数据矩阵化处理
# 模型相关库
from keras.models import load_model # 读取模型 。h5
from data_preprocessing import image_normaliazed # 归一化图像(实时化处理图像)
# 读取模型数据
model = load_model('model2.h5')
# 2、初始化变量
max_Speed = 30 # 速度最大值
steering_angle = -0.02 # 方向角
throttle = 0.3 # 油门 最大 1
# 3、创建网络连接
sio = socketio.Server() # 创建 服务器
app = Flask(__name__) # 定义 简单的服务器应用
app = socketio.WSGIApp(sio, app) # 链接 sio和app
# 定速巡航
class SimplePIController:
def __init__(self, Kp, Ki):
self.Kp = Kp
self.Ki = Ki
self.set_point = 0.
self.error = 0.
self.integral = 0.
def set_desired(self, desired):
self.set_point = desired
def update(self, measurement):
# proportional error
self.error = self.set_point - measurement
# integral error
self.integral += self.error
# print(self.integral)
return self.Kp * self.error + self.Ki * self.integral
# 4、发送控制 参数
def send_control(steering_angle, throttle):
sio.emit('steer', data={'steering_angle': steering_angle.__str__(), 'throttle': throttle.__str__()})
# 名字(自定义) ,数据(方向角、油门) data字典类数据
# 5、控制汽车运行——达到某种状态,进行特定操作
@sio.on('connect') # 当 连接(connect)成功——执行操作
def on_connect(sid, environ): # sid——电脑id
print('连接成功!')
@sio.on('telemetry') # 收到数据——操作 关键字
def on_telemetry(sid, data):
if data: # 判断data不为空
# print('我收到数据了')
# print('data')
speed = float(data['speed']) # 获取、输出 速度
print('Speed=', speed)
# base64.b64encode()数据进行编码转换为二进制
image = Image.open(BytesIO(base64.b64decode(data['image']))) # 电脑缓冲区获取图像,放到内存读取(打开)
image = np.array(image) # 将列表转化为数组
image =cv2.cvtColor(image,cv2.COLOR_BGR2RGB) # opencv打开图像是bgr格式
cv2.imshow('Image from Udacity Simulator',image)
cv2.waitKey(1) # 图像获取不到自动关闭
image = image_normaliazed(image) # 图像归一化处理
cv2.imshow('Image from after',image) # 显示处理后图像(名字,图像)
# 通过模型预测车辆行驶中 方向角
steering_angle = float(model.predict(np.array([image]))) # 输入图片信息,进行模型预测,类型转换
# mode.predict(x_text,batch_size,verbose) 测试集数据,一次性输入图像数量(实时读取-不设置),是否开启进度条(默认0)
throttle = controller.update(speed)
# throttle = 1.0 - steering_angle ** 2 - (speed / max_Speed) ** 2
# 控制速度(定速巡航) 防侧翻 steering_angle**2 当前速度、最大速度 比值 平方(正负号)
send_control(steering_angle, throttle) # 控制 运动
@sio.on('disconnect') # 当断开连接
def on_disconnect(sid):
print('断开连接')
# os.startfile(os.getcwd() + '/项目三 基于OpenCV的人脸识别说明文档.docx')
controller = SimplePIController(0.1, 0.002)
set_speed = 9
controller.set_desired(set_speed)
eventlet.wsgi.server(eventlet.listen(('', 4567)), app) # 连接服务器、客户端的 网关接口 端口值4567
# 运行之后,打开 模拟器(自动模式) —— 连接成功,收到数据{} 键值对