From 871969df9349c83b1d85316c74378bef14c6e9e8 Mon Sep 17 00:00:00 2001
From: ybnfsh <2329959058@qq.com>
Date: Sun, 28 Sep 2025 10:15:11 +0800
Subject: [PATCH 1/8] =?UTF-8?q?=E5=AE=8C=E6=88=90=E9=80=89=E9=A2=98?=
=?UTF-8?q?=E5=B9=B6=E6=8F=90=E4=BA=A4?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/driverless_car_yb/README.md | 1 +
1 file changed, 1 insertion(+)
create mode 100644 src/driverless_car_yb/README.md
diff --git a/src/driverless_car_yb/README.md b/src/driverless_car_yb/README.md
new file mode 100644
index 0000000000..8c27ba2124
--- /dev/null
+++ b/src/driverless_car_yb/README.md
@@ -0,0 +1 @@
+无人车
\ No newline at end of file
From 2897bfcf078a7baf6322dfa96496d2bb969a6dde Mon Sep 17 00:00:00 2001
From: ybnfsh <2329959058@qq.com>
Date: Mon, 17 Nov 2025 10:23:24 +0800
Subject: [PATCH 2/8] =?UTF-8?q?=E6=97=A0=E4=BA=BA=E8=BD=A6=E9=9C=80?=
=?UTF-8?q?=E8=A6=81=E5=9F=BA=E4=BA=8E=E5=8E=86=E5=8F=B2=E4=BC=A0=E6=84=9F?=
=?UTF-8?q?=E5=99=A8=E6=95=B0=E6=8D=AE=E9=A2=84=E6=B5=8B=E6=9C=AA=E6=9D=A5?=
=?UTF-8?q?=E8=BF=90=E5=8A=A8=E7=8A=B6=E6=80=81=E7=9A=84=E5=9C=BA=E6=99=AF?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/driverless_car_yb/main_speed.py | 161 ++++++++++++++++++++++++++++
1 file changed, 161 insertions(+)
create mode 100644 src/driverless_car_yb/main_speed.py
diff --git a/src/driverless_car_yb/main_speed.py b/src/driverless_car_yb/main_speed.py
new file mode 100644
index 0000000000..3afff2cae4
--- /dev/null
+++ b/src/driverless_car_yb/main_speed.py
@@ -0,0 +1,161 @@
+import torch
+import torch.nn as nn
+import torch.optim as optim
+import numpy as np
+import pandas as pd
+from sklearn.model_selection import train_test_split
+from sklearn.preprocessing import StandardScaler
+import matplotlib.pyplot as plt
+
+# 设置随机种子,保证结果可复现
+torch.manual_seed(42)
+np.random.seed(42)
+
+
+class SpeedPredictor(nn.Module):
+ """无人车速度预测模型:使用LSTM处理时序数据"""
+ def __init__(self, input_size, hidden_size, num_layers, output_size=1):
+ super(SpeedPredictor, self).__init__()
+ self.lstm = nn.LSTM(
+ input_size=input_size, # 输入特征数(如速度、加速度、方向盘角度等)
+ hidden_size=hidden_size, # LSTM隐藏层大小
+ num_layers=num_layers, # LSTM层数
+ batch_first=True # 输入格式为(batch, seq_len, input_size)
+ )
+ self.fc = nn.Linear(hidden_size, output_size) # 输出层(预测未来速度)
+
+ def forward(self, x):
+ # x shape: (batch_size, seq_len, input_size)
+ lstm_out, _ = self.lstm(x) # lstm_out shape: (batch_size, seq_len, hidden_size)
+ # 取最后一个时间步的输出用于预测
+ last_out = lstm_out[:, -1, :] # shape: (batch_size, hidden_size)
+ pred = self.fc(last_out) # shape: (batch_size, output_size)
+ return pred
+
+
+def create_sequences(data, seq_len, pred_len=1):
+ """
+ 将时序数据转换为输入序列和标签
+ data: 原始数据(特征矩阵)
+ seq_len: 输入序列长度(用过去多少个时间步预测未来)
+ pred_len: 预测未来多少个时间步(这里简化为1)
+ """
+ xs, ys = [], []
+ for i in range(len(data) - seq_len - pred_len + 1):
+ x = data[i:(i + seq_len)] # 输入序列(过去seq_len个时间步的特征)
+ y = data[i + seq_len:i + seq_len + pred_len, 0] # 标签(未来1个时间步的速度,假设第0列是速度)
+ xs.append(x)
+ ys.append(y)
+ return np.array(xs), np.array(ys)
+
+
+def main():
+ # 1. 数据准备(这里使用模拟数据,实际应用中替换为真实传感器数据)
+ # 模拟特征:[速度(m/s), 加速度(m/s²), 方向盘角度(°), 油门开度(%), 刹车压力(bar)]
+ num_samples = 10000
+ time = np.linspace(0, 100, num_samples)
+ speed = 10 + 5 * np.sin(time) + np.random.normal(0, 0.5, num_samples) # 带噪声的正弦曲线模拟速度
+ acceleration = np.gradient(speed, time) # 加速度(速度的导数)
+ steering = 10 * np.sin(time/2) + np.random.normal(0, 1, num_samples) # 方向盘角度
+ throttle = 30 + 10 * np.sin(time/3) + np.random.normal(0, 2, num_samples) # 油门开度
+ brake = np.where(speed < 8, 5 + np.random.normal(0, 1, num_samples), np.random.normal(0, 0.5, num_samples)) # 刹车压力
+
+ # 组合成特征矩阵
+ data = np.column_stack([speed, acceleration, steering, throttle, brake])
+
+ # 2. 数据预处理
+ scaler = StandardScaler() # 标准化(均值为0,方差为1)
+ data_scaled = scaler.fit_transform(data)
+
+ # 创建序列数据(用过去10个时间步预测未来1个时间步的速度)
+ seq_len = 10
+ X, y = create_sequences(data_scaled, seq_len)
+
+ # 划分训练集和测试集
+ X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, shuffle=False) # 时序数据不打乱顺序
+
+ # 转换为PyTorch张量
+ X_train = torch.FloatTensor(X_train)
+ y_train = torch.FloatTensor(y_train)
+ X_test = torch.FloatTensor(X_test)
+ y_test = torch.FloatTensor(y_test)
+
+ # 3. 模型初始化
+ input_size = X_train.shape[2] # 特征数(这里是5)
+ hidden_size = 64
+ num_layers = 2
+ model = SpeedPredictor(input_size, hidden_size, num_layers)
+
+ # 4. 定义损失函数和优化器
+ criterion = nn.MSELoss() # 均方误差损失(回归任务)
+ optimizer = optim.Adam(model.parameters(), lr=0.001)
+
+ # 5. 模型训练
+ epochs = 50
+ batch_size = 32
+ train_losses = []
+ test_losses = []
+
+ for epoch in range(epochs):
+ model.train() # 训练模式
+ epoch_loss = 0
+ # 分批训练
+ for i in range(0, len(X_train), batch_size):
+ batch_X = X_train[i:i+batch_size]
+ batch_y = y_train[i:i+batch_size]
+
+ optimizer.zero_grad() # 清零梯度
+ outputs = model(batch_X)
+ loss = criterion(outputs, batch_y)
+ loss.backward() # 反向传播
+ optimizer.step() # 更新参数
+
+ epoch_loss += loss.item() * batch_X.size(0) # 累计损失
+
+ train_loss = epoch_loss / len(X_train)
+ train_losses.append(train_loss)
+
+ # 测试集验证
+ model.eval() # 评估模式
+ with torch.no_grad():
+ y_pred = model(X_test)
+ test_loss = criterion(y_pred, y_test).item()
+ test_losses.append(test_loss)
+
+ if (epoch + 1) % 5 == 0:
+ print(f'Epoch [{epoch+1}/{epochs}], Train Loss: {train_loss:.6f}, Test Loss: {test_loss:.6f}')
+
+ # 6. 结果可视化
+ # 反标准化(将预测结果转换为原始速度尺度)
+ # 构造反标准化需要的虚拟特征矩阵(仅用于恢复速度的尺度)
+ dummy = np.zeros_like(data_scaled[:len(y_test)])
+ dummy[:, 0] = y_test.numpy().flatten() # 测试集真实速度(标准化后)
+ y_test_original = scaler.inverse_transform(dummy)[:, 0] # 原始尺度真实速度
+
+ dummy_pred = np.zeros_like(data_scaled[:len(y_test)])
+ dummy_pred[:, 0] = y_pred.numpy().flatten() # 预测速度(标准化后)
+ y_pred_original = scaler.inverse_transform(dummy_pred)[:, 0] # 原始尺度预测速度
+
+ # 绘制预测 vs 真实值
+ plt.figure(figsize=(12, 6))
+ plt.plot(y_test_original, label='真实速度', alpha=0.7)
+ plt.plot(y_pred_original, label='预测速度', alpha=0.7)
+ plt.xlabel('时间步')
+ plt.ylabel('速度 (m/s)')
+ plt.title('无人车速度预测结果')
+ plt.legend()
+ plt.show()
+
+ # 绘制损失曲线
+ plt.figure(figsize=(12, 6))
+ plt.plot(train_losses, label='训练损失')
+ plt.plot(test_losses, label='测试损失')
+ plt.xlabel('Epoch')
+ plt.ylabel('MSE损失')
+ plt.title('训练与测试损失曲线')
+ plt.legend()
+ plt.show()
+
+
+if __name__ == '__main__':
+ main()
\ No newline at end of file
From 507c6736a4449c0b60ae6562da77d3b046d6f2cd Mon Sep 17 00:00:00 2001
From: ybnfsh <2329959058@qq.com>
Date: Mon, 24 Nov 2025 09:22:23 +0800
Subject: [PATCH 3/8] =?UTF-8?q?=E5=AE=8C=E6=88=90=E9=80=89=E9=A2=98?=
=?UTF-8?q?=E5=B9=B6=E6=8F=90=E4=BA=A4?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/driverless _car_yb/main.direction.py | 275 +++++++++++++++++++++++
1 file changed, 275 insertions(+)
create mode 100644 src/driverless _car_yb/main.direction.py
diff --git a/src/driverless _car_yb/main.direction.py b/src/driverless _car_yb/main.direction.py
new file mode 100644
index 0000000000..efc22d79eb
--- /dev/null
+++ b/src/driverless _car_yb/main.direction.py
@@ -0,0 +1,275 @@
+import os
+import cv2
+import numpy as np
+import pandas as pd
+import matplotlib.pyplot as plt
+from sklearn.model_selection import train_test_split
+from tensorflow.keras.models import Sequential, load_model
+from tensorflow.keras.layers import Conv2D, MaxPooling2D, Flatten, Dense, Dropout, Lambda
+from tensorflow.keras.optimizers import Adam
+from tensorflow.keras.callbacks import ModelCheckpoint, EarlyStopping
+
+
+# --------------------------
+# 1. 数据生成与预处理
+# --------------------------
+def create_simulated_data(data_dir, num_samples=1000):
+ """
+ 创建模拟的驾驶数据(图像和转向角)
+ """
+ os.makedirs(data_dir, exist_ok=True)
+ os.makedirs(os.path.join(data_dir, 'images'), exist_ok=True)
+
+ # 生成转向角(-45度到45度之间)
+ steering_angles = np.random.uniform(-45, 45, num_samples)
+
+ # 创建CSV文件
+ data = {'image_path': [], 'steering_angle': []}
+
+ for i in range(num_samples):
+ # 生成模拟图像(道路场景)
+ img = np.zeros((240, 320, 3), dtype=np.uint8)
+
+ # 绘制道路
+ cv2.rectangle(img, (100, 0), (220, 240), (100, 100, 100), -1)
+
+ # 绘制车道线
+ cv2.line(img, (130, 0), (160, 240), (255, 255, 255), 2)
+ cv2.line(img, (190, 0), (160, 240), (255, 255, 255), 2)
+
+ # 根据转向角调整车道线
+ angle_rad = np.radians(steering_angles[i])
+ offset = int(50 * np.tan(angle_rad))
+
+ cv2.line(img, (130 + offset, 0), (160 + offset, 240), (0, 255, 0), 2)
+ cv2.line(img, (190 + offset, 0), (160 + offset, 240), (0, 255, 0), 2)
+
+ # 保存图像
+ img_path = os.path.join(data_dir, 'images', f'{i:04d}.jpg')
+ cv2.imwrite(img_path, img)
+
+ data['image_path'].append(img_path)
+ data['steering_angle'].append(steering_angles[i])
+
+ # 保存CSV文件
+ df = pd.DataFrame(data)
+ df.to_csv(os.path.join(data_dir, 'driving_log.csv'), index=False)
+ print(f"生成 {num_samples} 个模拟样本")
+ return df
+
+
+# 创建模拟数据
+data_dir = 'simulated_data'
+df = create_simulated_data(data_dir, num_samples=2000)
+
+
+# 数据增强函数
+def augment_image(img, angle):
+ """
+ 对图像进行增强处理
+ """
+ # 随机水平翻转
+ if np.random.rand() > 0.5:
+ img = cv2.flip(img, 1)
+ angle = -angle
+
+ # 随机调整亮度
+ hsv = cv2.cvtColor(img, cv2.COLOR_RGB2HSV)
+ brightness = np.random.uniform(0.7, 1.3)
+ hsv[:, :, 2] = np.clip(hsv[:, :, 2] * brightness, 0, 255)
+ img = cv2.cvtColor(hsv, cv2.COLOR_HSV2RGB)
+
+ # 随机裁剪
+ img = img[50:190, :, :] # 裁剪天空和地面部分
+
+ # 随机平移
+ tx = np.random.randint(-20, 20)
+ ty = np.random.randint(-10, 10)
+ M = np.float32([[1, 0, tx], [0, 1, ty]])
+ img = cv2.warpAffine(img, M, (img.shape[1], img.shape[0]))
+
+ return img, angle
+
+
+# 数据生成器
+def data_generator(df, batch_size=32, augment=True):
+ """
+ 生成批量训练数据
+ """
+ while True:
+ batch_images = []
+ batch_angles = []
+
+ # 随机打乱数据
+ shuffled_df = df.sample(frac=1).reset_index(drop=True)
+
+ for i in range(batch_size):
+ # 获取图像路径和转向角
+ img_path = shuffled_df.iloc[i]['image_path']
+ angle = shuffled_df.iloc[i]['steering_angle']
+
+ # 读取图像
+ img = cv2.imread(img_path)
+ img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
+
+ # 数据增强
+ if augment:
+ img, angle = augment_image(img, angle)
+
+ # 图像预处理
+ img = cv2.resize(img, (200, 66)) # 适应NVIDIA模型输入
+ img = img / 255.0 # 归一化
+
+ batch_images.append(img)
+ batch_angles.append(angle)
+
+ yield np.array(batch_images), np.array(batch_angles)
+
+
+# 划分训练集和验证集
+train_df, val_df = train_test_split(df, test_size=0.2, random_state=42)
+
+# 创建数据生成器
+train_generator = data_generator(train_df, batch_size=32, augment=True)
+val_generator = data_generator(val_df, batch_size=32, augment=False)
+
+
+# --------------------------
+# 2. 构建深度学习模型
+# --------------------------
+def build_model():
+ """
+ 构建基于CNN的转向角预测模型(参考NVIDIA架构)
+ """
+ model = Sequential()
+
+ # 图像预处理层
+ model.add(Lambda(lambda x: x / 255.0 - 0.5, input_shape=(66, 200, 3)))
+
+ # 卷积层
+ model.add(Conv2D(24, (5, 5), strides=(2, 2), activation='relu'))
+ model.add(Conv2D(36, (5, 5), strides=(2, 2), activation='relu'))
+ model.add(Conv2D(48, (5, 5), strides=(2, 2), activation='relu'))
+ model.add(Conv2D(64, (3, 3), activation='relu'))
+ model.add(Conv2D(64, (3, 3), activation='relu'))
+
+ # 全连接层
+ model.add(Flatten())
+ model.add(Dense(100, activation='relu'))
+ model.add(Dropout(0.5))
+ model.add(Dense(50, activation='relu'))
+ model.add(Dropout(0.5))
+ model.add(Dense(10, activation='relu'))
+ model.add(Dense(1)) # 输出转向角
+
+ # 编译模型
+ model.compile(optimizer=Adam(learning_rate=0.001), loss='mse')
+
+ return model
+
+
+# 构建模型
+model = build_model()
+model.summary()
+
+# --------------------------
+# 3. 训练模型
+# --------------------------
+# 定义回调函数
+checkpoint = ModelCheckpoint(
+ 'best_model.h5',
+ monitor='val_loss',
+ save_best_only=True,
+ mode='min',
+ verbose=1
+)
+
+early_stop = EarlyStopping(
+ monitor='val_loss',
+ patience=5,
+ mode='min',
+ verbose=1,
+ restore_best_weights=True
+)
+
+# 训练模型
+history = model.fit(
+ train_generator,
+ steps_per_epoch=len(train_df) // 32,
+ epochs=30,
+ validation_data=val_generator,
+ validation_steps=len(val_df) // 32,
+ callbacks=[checkpoint, early_stop],
+ verbose=1
+)
+
+# 绘制训练曲线
+plt.figure(figsize=(10, 5))
+plt.plot(history.history['loss'], label='训练损失')
+plt.plot(history.history['val_loss'], label='验证损失')
+plt.xlabel('Epoch')
+plt.ylabel('MSE损失')
+plt.legend()
+plt.title('训练过程')
+plt.show()
+
+# --------------------------
+# 4. 模型评估与实时预测
+# --------------------------
+# 加载最佳模型
+best_model = load_model('best_model.h5')
+
+# 在验证集上评估
+val_loss = best_model.evaluate(val_generator, steps=len(val_df) // 32, verbose=1)
+print(f"验证集损失: {val_loss:.4f}")
+
+
+# 实时预测演示
+def real_time_prediction(model):
+ """
+ 使用摄像头进行实时转向角预测
+ """
+ cap = cv2.VideoCapture(0)
+ cap.set(3, 320) # 设置宽度
+ cap.set(4, 240) # 设置高度
+
+ while True:
+ ret, frame = cap.read()
+ if not ret:
+ break
+
+ # 图像预处理
+ img = frame[50:190, :, :] # 裁剪
+ img = cv2.resize(img, (200, 66)) # 调整尺寸
+ img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) # 转换颜色空间
+ img = img / 255.0 # 归一化
+ img = np.expand_dims(img, axis=0) # 增加批次维度
+
+ # 预测转向角
+ steering_angle = model.predict(img)[0][0]
+
+ # 在图像上显示转向角
+ cv2.putText(
+ frame,
+ f"Steering Angle: {steering_angle:.2f} deg",
+ (10, 30),
+ cv2.FONT_HERSHEY_SIMPLEX,
+ 1,
+ (0, 255, 0),
+ 2
+ )
+
+ # 显示图像
+ cv2.imshow('Autonomous Driving', frame)
+
+ # 按'q'退出
+ if cv2.waitKey(1) & 0xFF == ord('q'):
+ break
+
+ cap.release()
+ cv2.destroyAllWindows()
+
+
+# 运行实时预测
+print("开始实时预测... 按'q'退出")
+real_time_prediction(best_model)
\ No newline at end of file
From dd24e637cd68fed9ec2ad74788ea439edda13e05 Mon Sep 17 00:00:00 2001
From: ybnfsh <2329959058@qq.com>
Date: Mon, 24 Nov 2025 09:25:56 +0800
Subject: [PATCH 4/8] =?UTF-8?q?=E6=97=A0=E4=BA=BA=E8=BD=A6=E6=96=B9?=
=?UTF-8?q?=E5=90=91=E6=94=B9=E5=8F=98=E7=9A=84=E6=B7=B1=E5=BA=A6=E5=AD=A6?=
=?UTF-8?q?=E4=B9=A0=E6=A8=A1=E5=9E=8B?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/driverless _car_yb/{main.direction.py => main.py} | 0
1 file changed, 0 insertions(+), 0 deletions(-)
rename src/driverless _car_yb/{main.direction.py => main.py} (100%)
diff --git a/src/driverless _car_yb/main.direction.py b/src/driverless _car_yb/main.py
similarity index 100%
rename from src/driverless _car_yb/main.direction.py
rename to src/driverless _car_yb/main.py
From c0478ec56e1bb82e921b729753e4257b317b28ed Mon Sep 17 00:00:00 2001
From: ybnfsh <2329959058@qq.com>
Date: Mon, 24 Nov 2025 09:32:35 +0800
Subject: [PATCH 5/8] =?UTF-8?q?=E6=97=A0=E4=BA=BA=E8=BD=A6=E6=96=B9?=
=?UTF-8?q?=E5=90=91=E6=94=B9=E5=8F=98=E7=9A=84=E6=B7=B1=E5=BA=A6=E5=AD=A6?=
=?UTF-8?q?=E4=B9=A0=E6=A8=A1=E5=9E=8B?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/driverless _car_yb/README.md | 161 +++++++++++++++++++++++++++++++
1 file changed, 161 insertions(+)
create mode 100644 src/driverless _car_yb/README.md
diff --git a/src/driverless _car_yb/README.md b/src/driverless _car_yb/README.md
new file mode 100644
index 0000000000..df84ba0f70
--- /dev/null
+++ b/src/driverless _car_yb/README.md
@@ -0,0 +1,161 @@
+无人车import torch
+import torch.nn as nn
+import torch.optim as optim
+import numpy as np
+import pandas as pd
+from sklearn.model_selection import train_test_split
+from sklearn.preprocessing import StandardScaler
+import matplotlib.pyplot as plt
+
+# 设置随机种子,保证结果可复现
+torch.manual_seed(42)
+np.random.seed(42)
+
+
+class SpeedPredictor(nn.Module):
+ """无人车速度预测模型:使用LSTM处理时序数据"""
+ def __init__(self, input_size, hidden_size, num_layers, output_size=1):
+ super(SpeedPredictor, self).__init__()
+ self.lstm = nn.LSTM(
+ input_size=input_size, # 输入特征数(如速度、加速度、方向盘角度等)
+ hidden_size=hidden_size, # LSTM隐藏层大小
+ num_layers=num_layers, # LSTM层数
+ batch_first=True # 输入格式为(batch, seq_len, input_size)
+ )
+ self.fc = nn.Linear(hidden_size, output_size) # 输出层(预测未来速度)
+
+ def forward(self, x):
+ # x shape: (batch_size, seq_len, input_size)
+ lstm_out, _ = self.lstm(x) # lstm_out shape: (batch_size, seq_len, hidden_size)
+ # 取最后一个时间步的输出用于预测
+ last_out = lstm_out[:, -1, :] # shape: (batch_size, hidden_size)
+ pred = self.fc(last_out) # shape: (batch_size, output_size)
+ return pred
+
+
+def create_sequences(data, seq_len, pred_len=1):
+ """
+ 将时序数据转换为输入序列和标签
+ data: 原始数据(特征矩阵)
+ seq_len: 输入序列长度(用过去多少个时间步预测未来)
+ pred_len: 预测未来多少个时间步(这里简化为1)
+ """
+ xs, ys = [], []
+ for i in range(len(data) - seq_len - pred_len + 1):
+ x = data[i:(i + seq_len)] # 输入序列(过去seq_len个时间步的特征)
+ y = data[i + seq_len:i + seq_len + pred_len, 0] # 标签(未来1个时间步的速度,假设第0列是速度)
+ xs.append(x)
+ ys.append(y)
+ return np.array(xs), np.array(ys)
+
+
+def main():
+ # 1. 数据准备(这里使用模拟数据,实际应用中替换为真实传感器数据)
+ # 模拟特征:[速度(m/s), 加速度(m/s²), 方向盘角度(°), 油门开度(%), 刹车压力(bar)]
+ num_samples = 10000
+ time = np.linspace(0, 100, num_samples)
+ speed = 10 + 5 * np.sin(time) + np.random.normal(0, 0.5, num_samples) # 带噪声的正弦曲线模拟速度
+ acceleration = np.gradient(speed, time) # 加速度(速度的导数)
+ steering = 10 * np.sin(time/2) + np.random.normal(0, 1, num_samples) # 方向盘角度
+ throttle = 30 + 10 * np.sin(time/3) + np.random.normal(0, 2, num_samples) # 油门开度
+ brake = np.where(speed < 8, 5 + np.random.normal(0, 1, num_samples), np.random.normal(0, 0.5, num_samples)) # 刹车压力
+
+ # 组合成特征矩阵
+ data = np.column_stack([speed, acceleration, steering, throttle, brake])
+
+ # 2. 数据预处理
+ scaler = StandardScaler() # 标准化(均值为0,方差为1)
+ data_scaled = scaler.fit_transform(data)
+
+ # 创建序列数据(用过去10个时间步预测未来1个时间步的速度)
+ seq_len = 10
+ X, y = create_sequences(data_scaled, seq_len)
+
+ # 划分训练集和测试集
+ X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, shuffle=False) # 时序数据不打乱顺序
+
+ # 转换为PyTorch张量
+ X_train = torch.FloatTensor(X_train)
+ y_train = torch.FloatTensor(y_train)
+ X_test = torch.FloatTensor(X_test)
+ y_test = torch.FloatTensor(y_test)
+
+ # 3. 模型初始化
+ input_size = X_train.shape[2] # 特征数(这里是5)
+ hidden_size = 64
+ num_layers = 2
+ model = SpeedPredictor(input_size, hidden_size, num_layers)
+
+ # 4. 定义损失函数和优化器
+ criterion = nn.MSELoss() # 均方误差损失(回归任务)
+ optimizer = optim.Adam(model.parameters(), lr=0.001)
+
+ # 5. 模型训练
+ epochs = 50
+ batch_size = 32
+ train_losses = []
+ test_losses = []
+
+ for epoch in range(epochs):
+ model.train() # 训练模式
+ epoch_loss = 0
+ # 分批训练
+ for i in range(0, len(X_train), batch_size):
+ batch_X = X_train[i:i+batch_size]
+ batch_y = y_train[i:i+batch_size]
+
+ optimizer.zero_grad() # 清零梯度
+ outputs = model(batch_X)
+ loss = criterion(outputs, batch_y)
+ loss.backward() # 反向传播
+ optimizer.step() # 更新参数
+
+ epoch_loss += loss.item() * batch_X.size(0) # 累计损失
+
+ train_loss = epoch_loss / len(X_train)
+ train_losses.append(train_loss)
+
+ # 测试集验证
+ model.eval() # 评估模式
+ with torch.no_grad():
+ y_pred = model(X_test)
+ test_loss = criterion(y_pred, y_test).item()
+ test_losses.append(test_loss)
+
+ if (epoch + 1) % 5 == 0:
+ print(f'Epoch [{epoch+1}/{epochs}], Train Loss: {train_loss:.6f}, Test Loss: {test_loss:.6f}')
+
+ # 6. 结果可视化
+ # 反标准化(将预测结果转换为原始速度尺度)
+ # 构造反标准化需要的虚拟特征矩阵(仅用于恢复速度的尺度)
+ dummy = np.zeros_like(data_scaled[:len(y_test)])
+ dummy[:, 0] = y_test.numpy().flatten() # 测试集真实速度(标准化后)
+ y_test_original = scaler.inverse_transform(dummy)[:, 0] # 原始尺度真实速度
+
+ dummy_pred = np.zeros_like(data_scaled[:len(y_test)])
+ dummy_pred[:, 0] = y_pred.numpy().flatten() # 预测速度(标准化后)
+ y_pred_original = scaler.inverse_transform(dummy_pred)[:, 0] # 原始尺度预测速度
+
+ # 绘制预测 vs 真实值
+ plt.figure(figsize=(12, 6))
+ plt.plot(y_test_original, label='真实速度', alpha=0.7)
+ plt.plot(y_pred_original, label='预测速度', alpha=0.7)
+ plt.xlabel('时间步')
+ plt.ylabel('速度 (m/s)')
+ plt.title('无人车速度预测结果')
+ plt.legend()
+ plt.show()
+
+ # 绘制损失曲线
+ plt.figure(figsize=(12, 6))
+ plt.plot(train_losses, label='训练损失')
+ plt.plot(test_losses, label='测试损失')
+ plt.xlabel('Epoch')
+ plt.ylabel('MSE损失')
+ plt.title('训练与测试损失曲线')
+ plt.legend()
+ plt.show()
+
+
+if __name__ == '__main__':
+ main()这段代码有什么功能
\ No newline at end of file
From 73f98bda8377bd445321a641f6a72ec3b0342e43 Mon Sep 17 00:00:00 2001
From: ybnfsh <2329959058@qq.com>
Date: Mon, 24 Nov 2025 10:54:11 +0800
Subject: [PATCH 6/8] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=96=87=E4=BB=B6?=
=?UTF-8?q?=E5=90=8D?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.idea/.gitignore | 3 +
.../inspectionProfiles/profiles_settings.xml | 6 +
.idea/misc.xml | 7 +
.idea/modules.xml | 8 +
.idea/nn.iml | 14 +
.idea/vcs.xml | 6 +
src/driverless _car_yb/README.md | 161 ----------
src/driverless _car_yb/main.py | 275 ------------------
8 files changed, 44 insertions(+), 436 deletions(-)
create mode 100644 .idea/.gitignore
create mode 100644 .idea/inspectionProfiles/profiles_settings.xml
create mode 100644 .idea/misc.xml
create mode 100644 .idea/modules.xml
create mode 100644 .idea/nn.iml
create mode 100644 .idea/vcs.xml
delete mode 100644 src/driverless _car_yb/README.md
delete mode 100644 src/driverless _car_yb/main.py
diff --git a/.idea/.gitignore b/.idea/.gitignore
new file mode 100644
index 0000000000..359bb5307e
--- /dev/null
+++ b/.idea/.gitignore
@@ -0,0 +1,3 @@
+# 默认忽略的文件
+/shelf/
+/workspace.xml
diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml
new file mode 100644
index 0000000000..105ce2da2d
--- /dev/null
+++ b/.idea/inspectionProfiles/profiles_settings.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644
index 0000000000..25d4c9c531
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 0000000000..0e01bed9d6
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/nn.iml b/.idea/nn.iml
new file mode 100644
index 0000000000..a80c2ef563
--- /dev/null
+++ b/.idea/nn.iml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000000..35eb1ddfbb
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/driverless _car_yb/README.md b/src/driverless _car_yb/README.md
deleted file mode 100644
index df84ba0f70..0000000000
--- a/src/driverless _car_yb/README.md
+++ /dev/null
@@ -1,161 +0,0 @@
-无人车import torch
-import torch.nn as nn
-import torch.optim as optim
-import numpy as np
-import pandas as pd
-from sklearn.model_selection import train_test_split
-from sklearn.preprocessing import StandardScaler
-import matplotlib.pyplot as plt
-
-# 设置随机种子,保证结果可复现
-torch.manual_seed(42)
-np.random.seed(42)
-
-
-class SpeedPredictor(nn.Module):
- """无人车速度预测模型:使用LSTM处理时序数据"""
- def __init__(self, input_size, hidden_size, num_layers, output_size=1):
- super(SpeedPredictor, self).__init__()
- self.lstm = nn.LSTM(
- input_size=input_size, # 输入特征数(如速度、加速度、方向盘角度等)
- hidden_size=hidden_size, # LSTM隐藏层大小
- num_layers=num_layers, # LSTM层数
- batch_first=True # 输入格式为(batch, seq_len, input_size)
- )
- self.fc = nn.Linear(hidden_size, output_size) # 输出层(预测未来速度)
-
- def forward(self, x):
- # x shape: (batch_size, seq_len, input_size)
- lstm_out, _ = self.lstm(x) # lstm_out shape: (batch_size, seq_len, hidden_size)
- # 取最后一个时间步的输出用于预测
- last_out = lstm_out[:, -1, :] # shape: (batch_size, hidden_size)
- pred = self.fc(last_out) # shape: (batch_size, output_size)
- return pred
-
-
-def create_sequences(data, seq_len, pred_len=1):
- """
- 将时序数据转换为输入序列和标签
- data: 原始数据(特征矩阵)
- seq_len: 输入序列长度(用过去多少个时间步预测未来)
- pred_len: 预测未来多少个时间步(这里简化为1)
- """
- xs, ys = [], []
- for i in range(len(data) - seq_len - pred_len + 1):
- x = data[i:(i + seq_len)] # 输入序列(过去seq_len个时间步的特征)
- y = data[i + seq_len:i + seq_len + pred_len, 0] # 标签(未来1个时间步的速度,假设第0列是速度)
- xs.append(x)
- ys.append(y)
- return np.array(xs), np.array(ys)
-
-
-def main():
- # 1. 数据准备(这里使用模拟数据,实际应用中替换为真实传感器数据)
- # 模拟特征:[速度(m/s), 加速度(m/s²), 方向盘角度(°), 油门开度(%), 刹车压力(bar)]
- num_samples = 10000
- time = np.linspace(0, 100, num_samples)
- speed = 10 + 5 * np.sin(time) + np.random.normal(0, 0.5, num_samples) # 带噪声的正弦曲线模拟速度
- acceleration = np.gradient(speed, time) # 加速度(速度的导数)
- steering = 10 * np.sin(time/2) + np.random.normal(0, 1, num_samples) # 方向盘角度
- throttle = 30 + 10 * np.sin(time/3) + np.random.normal(0, 2, num_samples) # 油门开度
- brake = np.where(speed < 8, 5 + np.random.normal(0, 1, num_samples), np.random.normal(0, 0.5, num_samples)) # 刹车压力
-
- # 组合成特征矩阵
- data = np.column_stack([speed, acceleration, steering, throttle, brake])
-
- # 2. 数据预处理
- scaler = StandardScaler() # 标准化(均值为0,方差为1)
- data_scaled = scaler.fit_transform(data)
-
- # 创建序列数据(用过去10个时间步预测未来1个时间步的速度)
- seq_len = 10
- X, y = create_sequences(data_scaled, seq_len)
-
- # 划分训练集和测试集
- X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, shuffle=False) # 时序数据不打乱顺序
-
- # 转换为PyTorch张量
- X_train = torch.FloatTensor(X_train)
- y_train = torch.FloatTensor(y_train)
- X_test = torch.FloatTensor(X_test)
- y_test = torch.FloatTensor(y_test)
-
- # 3. 模型初始化
- input_size = X_train.shape[2] # 特征数(这里是5)
- hidden_size = 64
- num_layers = 2
- model = SpeedPredictor(input_size, hidden_size, num_layers)
-
- # 4. 定义损失函数和优化器
- criterion = nn.MSELoss() # 均方误差损失(回归任务)
- optimizer = optim.Adam(model.parameters(), lr=0.001)
-
- # 5. 模型训练
- epochs = 50
- batch_size = 32
- train_losses = []
- test_losses = []
-
- for epoch in range(epochs):
- model.train() # 训练模式
- epoch_loss = 0
- # 分批训练
- for i in range(0, len(X_train), batch_size):
- batch_X = X_train[i:i+batch_size]
- batch_y = y_train[i:i+batch_size]
-
- optimizer.zero_grad() # 清零梯度
- outputs = model(batch_X)
- loss = criterion(outputs, batch_y)
- loss.backward() # 反向传播
- optimizer.step() # 更新参数
-
- epoch_loss += loss.item() * batch_X.size(0) # 累计损失
-
- train_loss = epoch_loss / len(X_train)
- train_losses.append(train_loss)
-
- # 测试集验证
- model.eval() # 评估模式
- with torch.no_grad():
- y_pred = model(X_test)
- test_loss = criterion(y_pred, y_test).item()
- test_losses.append(test_loss)
-
- if (epoch + 1) % 5 == 0:
- print(f'Epoch [{epoch+1}/{epochs}], Train Loss: {train_loss:.6f}, Test Loss: {test_loss:.6f}')
-
- # 6. 结果可视化
- # 反标准化(将预测结果转换为原始速度尺度)
- # 构造反标准化需要的虚拟特征矩阵(仅用于恢复速度的尺度)
- dummy = np.zeros_like(data_scaled[:len(y_test)])
- dummy[:, 0] = y_test.numpy().flatten() # 测试集真实速度(标准化后)
- y_test_original = scaler.inverse_transform(dummy)[:, 0] # 原始尺度真实速度
-
- dummy_pred = np.zeros_like(data_scaled[:len(y_test)])
- dummy_pred[:, 0] = y_pred.numpy().flatten() # 预测速度(标准化后)
- y_pred_original = scaler.inverse_transform(dummy_pred)[:, 0] # 原始尺度预测速度
-
- # 绘制预测 vs 真实值
- plt.figure(figsize=(12, 6))
- plt.plot(y_test_original, label='真实速度', alpha=0.7)
- plt.plot(y_pred_original, label='预测速度', alpha=0.7)
- plt.xlabel('时间步')
- plt.ylabel('速度 (m/s)')
- plt.title('无人车速度预测结果')
- plt.legend()
- plt.show()
-
- # 绘制损失曲线
- plt.figure(figsize=(12, 6))
- plt.plot(train_losses, label='训练损失')
- plt.plot(test_losses, label='测试损失')
- plt.xlabel('Epoch')
- plt.ylabel('MSE损失')
- plt.title('训练与测试损失曲线')
- plt.legend()
- plt.show()
-
-
-if __name__ == '__main__':
- main()这段代码有什么功能
\ No newline at end of file
diff --git a/src/driverless _car_yb/main.py b/src/driverless _car_yb/main.py
deleted file mode 100644
index efc22d79eb..0000000000
--- a/src/driverless _car_yb/main.py
+++ /dev/null
@@ -1,275 +0,0 @@
-import os
-import cv2
-import numpy as np
-import pandas as pd
-import matplotlib.pyplot as plt
-from sklearn.model_selection import train_test_split
-from tensorflow.keras.models import Sequential, load_model
-from tensorflow.keras.layers import Conv2D, MaxPooling2D, Flatten, Dense, Dropout, Lambda
-from tensorflow.keras.optimizers import Adam
-from tensorflow.keras.callbacks import ModelCheckpoint, EarlyStopping
-
-
-# --------------------------
-# 1. 数据生成与预处理
-# --------------------------
-def create_simulated_data(data_dir, num_samples=1000):
- """
- 创建模拟的驾驶数据(图像和转向角)
- """
- os.makedirs(data_dir, exist_ok=True)
- os.makedirs(os.path.join(data_dir, 'images'), exist_ok=True)
-
- # 生成转向角(-45度到45度之间)
- steering_angles = np.random.uniform(-45, 45, num_samples)
-
- # 创建CSV文件
- data = {'image_path': [], 'steering_angle': []}
-
- for i in range(num_samples):
- # 生成模拟图像(道路场景)
- img = np.zeros((240, 320, 3), dtype=np.uint8)
-
- # 绘制道路
- cv2.rectangle(img, (100, 0), (220, 240), (100, 100, 100), -1)
-
- # 绘制车道线
- cv2.line(img, (130, 0), (160, 240), (255, 255, 255), 2)
- cv2.line(img, (190, 0), (160, 240), (255, 255, 255), 2)
-
- # 根据转向角调整车道线
- angle_rad = np.radians(steering_angles[i])
- offset = int(50 * np.tan(angle_rad))
-
- cv2.line(img, (130 + offset, 0), (160 + offset, 240), (0, 255, 0), 2)
- cv2.line(img, (190 + offset, 0), (160 + offset, 240), (0, 255, 0), 2)
-
- # 保存图像
- img_path = os.path.join(data_dir, 'images', f'{i:04d}.jpg')
- cv2.imwrite(img_path, img)
-
- data['image_path'].append(img_path)
- data['steering_angle'].append(steering_angles[i])
-
- # 保存CSV文件
- df = pd.DataFrame(data)
- df.to_csv(os.path.join(data_dir, 'driving_log.csv'), index=False)
- print(f"生成 {num_samples} 个模拟样本")
- return df
-
-
-# 创建模拟数据
-data_dir = 'simulated_data'
-df = create_simulated_data(data_dir, num_samples=2000)
-
-
-# 数据增强函数
-def augment_image(img, angle):
- """
- 对图像进行增强处理
- """
- # 随机水平翻转
- if np.random.rand() > 0.5:
- img = cv2.flip(img, 1)
- angle = -angle
-
- # 随机调整亮度
- hsv = cv2.cvtColor(img, cv2.COLOR_RGB2HSV)
- brightness = np.random.uniform(0.7, 1.3)
- hsv[:, :, 2] = np.clip(hsv[:, :, 2] * brightness, 0, 255)
- img = cv2.cvtColor(hsv, cv2.COLOR_HSV2RGB)
-
- # 随机裁剪
- img = img[50:190, :, :] # 裁剪天空和地面部分
-
- # 随机平移
- tx = np.random.randint(-20, 20)
- ty = np.random.randint(-10, 10)
- M = np.float32([[1, 0, tx], [0, 1, ty]])
- img = cv2.warpAffine(img, M, (img.shape[1], img.shape[0]))
-
- return img, angle
-
-
-# 数据生成器
-def data_generator(df, batch_size=32, augment=True):
- """
- 生成批量训练数据
- """
- while True:
- batch_images = []
- batch_angles = []
-
- # 随机打乱数据
- shuffled_df = df.sample(frac=1).reset_index(drop=True)
-
- for i in range(batch_size):
- # 获取图像路径和转向角
- img_path = shuffled_df.iloc[i]['image_path']
- angle = shuffled_df.iloc[i]['steering_angle']
-
- # 读取图像
- img = cv2.imread(img_path)
- img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
-
- # 数据增强
- if augment:
- img, angle = augment_image(img, angle)
-
- # 图像预处理
- img = cv2.resize(img, (200, 66)) # 适应NVIDIA模型输入
- img = img / 255.0 # 归一化
-
- batch_images.append(img)
- batch_angles.append(angle)
-
- yield np.array(batch_images), np.array(batch_angles)
-
-
-# 划分训练集和验证集
-train_df, val_df = train_test_split(df, test_size=0.2, random_state=42)
-
-# 创建数据生成器
-train_generator = data_generator(train_df, batch_size=32, augment=True)
-val_generator = data_generator(val_df, batch_size=32, augment=False)
-
-
-# --------------------------
-# 2. 构建深度学习模型
-# --------------------------
-def build_model():
- """
- 构建基于CNN的转向角预测模型(参考NVIDIA架构)
- """
- model = Sequential()
-
- # 图像预处理层
- model.add(Lambda(lambda x: x / 255.0 - 0.5, input_shape=(66, 200, 3)))
-
- # 卷积层
- model.add(Conv2D(24, (5, 5), strides=(2, 2), activation='relu'))
- model.add(Conv2D(36, (5, 5), strides=(2, 2), activation='relu'))
- model.add(Conv2D(48, (5, 5), strides=(2, 2), activation='relu'))
- model.add(Conv2D(64, (3, 3), activation='relu'))
- model.add(Conv2D(64, (3, 3), activation='relu'))
-
- # 全连接层
- model.add(Flatten())
- model.add(Dense(100, activation='relu'))
- model.add(Dropout(0.5))
- model.add(Dense(50, activation='relu'))
- model.add(Dropout(0.5))
- model.add(Dense(10, activation='relu'))
- model.add(Dense(1)) # 输出转向角
-
- # 编译模型
- model.compile(optimizer=Adam(learning_rate=0.001), loss='mse')
-
- return model
-
-
-# 构建模型
-model = build_model()
-model.summary()
-
-# --------------------------
-# 3. 训练模型
-# --------------------------
-# 定义回调函数
-checkpoint = ModelCheckpoint(
- 'best_model.h5',
- monitor='val_loss',
- save_best_only=True,
- mode='min',
- verbose=1
-)
-
-early_stop = EarlyStopping(
- monitor='val_loss',
- patience=5,
- mode='min',
- verbose=1,
- restore_best_weights=True
-)
-
-# 训练模型
-history = model.fit(
- train_generator,
- steps_per_epoch=len(train_df) // 32,
- epochs=30,
- validation_data=val_generator,
- validation_steps=len(val_df) // 32,
- callbacks=[checkpoint, early_stop],
- verbose=1
-)
-
-# 绘制训练曲线
-plt.figure(figsize=(10, 5))
-plt.plot(history.history['loss'], label='训练损失')
-plt.plot(history.history['val_loss'], label='验证损失')
-plt.xlabel('Epoch')
-plt.ylabel('MSE损失')
-plt.legend()
-plt.title('训练过程')
-plt.show()
-
-# --------------------------
-# 4. 模型评估与实时预测
-# --------------------------
-# 加载最佳模型
-best_model = load_model('best_model.h5')
-
-# 在验证集上评估
-val_loss = best_model.evaluate(val_generator, steps=len(val_df) // 32, verbose=1)
-print(f"验证集损失: {val_loss:.4f}")
-
-
-# 实时预测演示
-def real_time_prediction(model):
- """
- 使用摄像头进行实时转向角预测
- """
- cap = cv2.VideoCapture(0)
- cap.set(3, 320) # 设置宽度
- cap.set(4, 240) # 设置高度
-
- while True:
- ret, frame = cap.read()
- if not ret:
- break
-
- # 图像预处理
- img = frame[50:190, :, :] # 裁剪
- img = cv2.resize(img, (200, 66)) # 调整尺寸
- img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) # 转换颜色空间
- img = img / 255.0 # 归一化
- img = np.expand_dims(img, axis=0) # 增加批次维度
-
- # 预测转向角
- steering_angle = model.predict(img)[0][0]
-
- # 在图像上显示转向角
- cv2.putText(
- frame,
- f"Steering Angle: {steering_angle:.2f} deg",
- (10, 30),
- cv2.FONT_HERSHEY_SIMPLEX,
- 1,
- (0, 255, 0),
- 2
- )
-
- # 显示图像
- cv2.imshow('Autonomous Driving', frame)
-
- # 按'q'退出
- if cv2.waitKey(1) & 0xFF == ord('q'):
- break
-
- cap.release()
- cv2.destroyAllWindows()
-
-
-# 运行实时预测
-print("开始实时预测... 按'q'退出")
-real_time_prediction(best_model)
\ No newline at end of file
From 91f07a59b24fdeac035b4ec6c4d726399f71ba30 Mon Sep 17 00:00:00 2001
From: ybnfsh <2329959058@qq.com>
Date: Tue, 25 Nov 2025 10:44:50 +0800
Subject: [PATCH 7/8] =?UTF-8?q?=E6=8F=90=E4=BA=A4=E6=97=A0=E4=BA=BA?=
=?UTF-8?q?=E8=BD=A6=E6=96=B9=E5=90=91=E6=94=B9=E5=8F=98=E4=BB=A3=E7=A0=81?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/driverless_car_yb/main.py | 275 ++++++++++++++++++++++++++++++++++
1 file changed, 275 insertions(+)
create mode 100644 src/driverless_car_yb/main.py
diff --git a/src/driverless_car_yb/main.py b/src/driverless_car_yb/main.py
new file mode 100644
index 0000000000..efc22d79eb
--- /dev/null
+++ b/src/driverless_car_yb/main.py
@@ -0,0 +1,275 @@
+import os
+import cv2
+import numpy as np
+import pandas as pd
+import matplotlib.pyplot as plt
+from sklearn.model_selection import train_test_split
+from tensorflow.keras.models import Sequential, load_model
+from tensorflow.keras.layers import Conv2D, MaxPooling2D, Flatten, Dense, Dropout, Lambda
+from tensorflow.keras.optimizers import Adam
+from tensorflow.keras.callbacks import ModelCheckpoint, EarlyStopping
+
+
+# --------------------------
+# 1. 数据生成与预处理
+# --------------------------
+def create_simulated_data(data_dir, num_samples=1000):
+ """
+ 创建模拟的驾驶数据(图像和转向角)
+ """
+ os.makedirs(data_dir, exist_ok=True)
+ os.makedirs(os.path.join(data_dir, 'images'), exist_ok=True)
+
+ # 生成转向角(-45度到45度之间)
+ steering_angles = np.random.uniform(-45, 45, num_samples)
+
+ # 创建CSV文件
+ data = {'image_path': [], 'steering_angle': []}
+
+ for i in range(num_samples):
+ # 生成模拟图像(道路场景)
+ img = np.zeros((240, 320, 3), dtype=np.uint8)
+
+ # 绘制道路
+ cv2.rectangle(img, (100, 0), (220, 240), (100, 100, 100), -1)
+
+ # 绘制车道线
+ cv2.line(img, (130, 0), (160, 240), (255, 255, 255), 2)
+ cv2.line(img, (190, 0), (160, 240), (255, 255, 255), 2)
+
+ # 根据转向角调整车道线
+ angle_rad = np.radians(steering_angles[i])
+ offset = int(50 * np.tan(angle_rad))
+
+ cv2.line(img, (130 + offset, 0), (160 + offset, 240), (0, 255, 0), 2)
+ cv2.line(img, (190 + offset, 0), (160 + offset, 240), (0, 255, 0), 2)
+
+ # 保存图像
+ img_path = os.path.join(data_dir, 'images', f'{i:04d}.jpg')
+ cv2.imwrite(img_path, img)
+
+ data['image_path'].append(img_path)
+ data['steering_angle'].append(steering_angles[i])
+
+ # 保存CSV文件
+ df = pd.DataFrame(data)
+ df.to_csv(os.path.join(data_dir, 'driving_log.csv'), index=False)
+ print(f"生成 {num_samples} 个模拟样本")
+ return df
+
+
+# 创建模拟数据
+data_dir = 'simulated_data'
+df = create_simulated_data(data_dir, num_samples=2000)
+
+
+# 数据增强函数
+def augment_image(img, angle):
+ """
+ 对图像进行增强处理
+ """
+ # 随机水平翻转
+ if np.random.rand() > 0.5:
+ img = cv2.flip(img, 1)
+ angle = -angle
+
+ # 随机调整亮度
+ hsv = cv2.cvtColor(img, cv2.COLOR_RGB2HSV)
+ brightness = np.random.uniform(0.7, 1.3)
+ hsv[:, :, 2] = np.clip(hsv[:, :, 2] * brightness, 0, 255)
+ img = cv2.cvtColor(hsv, cv2.COLOR_HSV2RGB)
+
+ # 随机裁剪
+ img = img[50:190, :, :] # 裁剪天空和地面部分
+
+ # 随机平移
+ tx = np.random.randint(-20, 20)
+ ty = np.random.randint(-10, 10)
+ M = np.float32([[1, 0, tx], [0, 1, ty]])
+ img = cv2.warpAffine(img, M, (img.shape[1], img.shape[0]))
+
+ return img, angle
+
+
+# 数据生成器
+def data_generator(df, batch_size=32, augment=True):
+ """
+ 生成批量训练数据
+ """
+ while True:
+ batch_images = []
+ batch_angles = []
+
+ # 随机打乱数据
+ shuffled_df = df.sample(frac=1).reset_index(drop=True)
+
+ for i in range(batch_size):
+ # 获取图像路径和转向角
+ img_path = shuffled_df.iloc[i]['image_path']
+ angle = shuffled_df.iloc[i]['steering_angle']
+
+ # 读取图像
+ img = cv2.imread(img_path)
+ img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
+
+ # 数据增强
+ if augment:
+ img, angle = augment_image(img, angle)
+
+ # 图像预处理
+ img = cv2.resize(img, (200, 66)) # 适应NVIDIA模型输入
+ img = img / 255.0 # 归一化
+
+ batch_images.append(img)
+ batch_angles.append(angle)
+
+ yield np.array(batch_images), np.array(batch_angles)
+
+
+# 划分训练集和验证集
+train_df, val_df = train_test_split(df, test_size=0.2, random_state=42)
+
+# 创建数据生成器
+train_generator = data_generator(train_df, batch_size=32, augment=True)
+val_generator = data_generator(val_df, batch_size=32, augment=False)
+
+
+# --------------------------
+# 2. 构建深度学习模型
+# --------------------------
+def build_model():
+ """
+ 构建基于CNN的转向角预测模型(参考NVIDIA架构)
+ """
+ model = Sequential()
+
+ # 图像预处理层
+ model.add(Lambda(lambda x: x / 255.0 - 0.5, input_shape=(66, 200, 3)))
+
+ # 卷积层
+ model.add(Conv2D(24, (5, 5), strides=(2, 2), activation='relu'))
+ model.add(Conv2D(36, (5, 5), strides=(2, 2), activation='relu'))
+ model.add(Conv2D(48, (5, 5), strides=(2, 2), activation='relu'))
+ model.add(Conv2D(64, (3, 3), activation='relu'))
+ model.add(Conv2D(64, (3, 3), activation='relu'))
+
+ # 全连接层
+ model.add(Flatten())
+ model.add(Dense(100, activation='relu'))
+ model.add(Dropout(0.5))
+ model.add(Dense(50, activation='relu'))
+ model.add(Dropout(0.5))
+ model.add(Dense(10, activation='relu'))
+ model.add(Dense(1)) # 输出转向角
+
+ # 编译模型
+ model.compile(optimizer=Adam(learning_rate=0.001), loss='mse')
+
+ return model
+
+
+# 构建模型
+model = build_model()
+model.summary()
+
+# --------------------------
+# 3. 训练模型
+# --------------------------
+# 定义回调函数
+checkpoint = ModelCheckpoint(
+ 'best_model.h5',
+ monitor='val_loss',
+ save_best_only=True,
+ mode='min',
+ verbose=1
+)
+
+early_stop = EarlyStopping(
+ monitor='val_loss',
+ patience=5,
+ mode='min',
+ verbose=1,
+ restore_best_weights=True
+)
+
+# 训练模型
+history = model.fit(
+ train_generator,
+ steps_per_epoch=len(train_df) // 32,
+ epochs=30,
+ validation_data=val_generator,
+ validation_steps=len(val_df) // 32,
+ callbacks=[checkpoint, early_stop],
+ verbose=1
+)
+
+# 绘制训练曲线
+plt.figure(figsize=(10, 5))
+plt.plot(history.history['loss'], label='训练损失')
+plt.plot(history.history['val_loss'], label='验证损失')
+plt.xlabel('Epoch')
+plt.ylabel('MSE损失')
+plt.legend()
+plt.title('训练过程')
+plt.show()
+
+# --------------------------
+# 4. 模型评估与实时预测
+# --------------------------
+# 加载最佳模型
+best_model = load_model('best_model.h5')
+
+# 在验证集上评估
+val_loss = best_model.evaluate(val_generator, steps=len(val_df) // 32, verbose=1)
+print(f"验证集损失: {val_loss:.4f}")
+
+
+# 实时预测演示
+def real_time_prediction(model):
+ """
+ 使用摄像头进行实时转向角预测
+ """
+ cap = cv2.VideoCapture(0)
+ cap.set(3, 320) # 设置宽度
+ cap.set(4, 240) # 设置高度
+
+ while True:
+ ret, frame = cap.read()
+ if not ret:
+ break
+
+ # 图像预处理
+ img = frame[50:190, :, :] # 裁剪
+ img = cv2.resize(img, (200, 66)) # 调整尺寸
+ img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) # 转换颜色空间
+ img = img / 255.0 # 归一化
+ img = np.expand_dims(img, axis=0) # 增加批次维度
+
+ # 预测转向角
+ steering_angle = model.predict(img)[0][0]
+
+ # 在图像上显示转向角
+ cv2.putText(
+ frame,
+ f"Steering Angle: {steering_angle:.2f} deg",
+ (10, 30),
+ cv2.FONT_HERSHEY_SIMPLEX,
+ 1,
+ (0, 255, 0),
+ 2
+ )
+
+ # 显示图像
+ cv2.imshow('Autonomous Driving', frame)
+
+ # 按'q'退出
+ if cv2.waitKey(1) & 0xFF == ord('q'):
+ break
+
+ cap.release()
+ cv2.destroyAllWindows()
+
+
+# 运行实时预测
+print("开始实时预测... 按'q'退出")
+real_time_prediction(best_model)
\ No newline at end of file
From 95a0709fc6da5e33c2cf720486a7993594596913 Mon Sep 17 00:00:00 2001
From: ybnfsh <2329959058@qq.com>
Date: Tue, 25 Nov 2025 10:44:50 +0800
Subject: [PATCH 8/8] =?UTF-8?q?=E4=BF=AE=E6=94=B9README.md?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/driverless_car_yb/README.md | 24 +++++++++++++++++++++++-
1 file changed, 23 insertions(+), 1 deletion(-)
diff --git a/src/driverless_car_yb/README.md b/src/driverless_car_yb/README.md
index 8c27ba2124..31c342a6a0 100644
--- a/src/driverless_car_yb/README.md
+++ b/src/driverless_car_yb/README.md
@@ -1 +1,23 @@
-无人车
\ No newline at end of file
+# 无人车项目
+
+## 项目简介
+无人车(自动驾驶汽车)是一种集成了人工智能、传感器技术、计算机视觉和机器学习等前沿技术的智能交通工具。该项目旨在开发能够在复杂道路环境中自主导航、避障、识别交通标志并安全行驶的无人驾驶系统。
+
+## 核心技术
+**计算机视觉**:通过摄像头识别道路标志、车辆、行人等
+**传感器融合**:整合激光雷达、毫米波雷达等传感器数据
+**路径规划**:基于实时环境信息规划最优行驶路径
+**决策系统**:处理复杂交通场景并做出驾驶决策
+**机器学习**:通过深度学习模型提升驾驶安全性
+
+## 主要功能
+自动跟车与变道
+智能避障与紧急制动
+自动泊车
+语音控制与导航
+实时路况分析
+
+## 技术优势
+本项目采用模块化架构设计,支持多种传感器配置和算法策略,确保系统的可扩展性和稳定性。通过大规模数据训练和仿真测试,持续优化算法性能。
+
+---
\ No newline at end of file