在这里插入图片描述
该方案的核心特点是利用Q-Learning算法实现多智能体在动态环境下的自主避障与队形保持,通过状态-动作-奖励的闭环学习机制替代传统硬编码规则,结合BLDC电机的高动态响应实现灵活编队机动;主要适用于仓储物流、特种作业、科研验证等场景;实际部署需重点解决Arduino算力瓶颈、Q表维度灾难、通信延迟及奖励函数设计等问题。

一、主要特点
Q-Learning强化学习——从"规则驱动"到"自主学习"
传统避障编队依赖人工设计的规则(如人工势场法、领航-跟随法),在复杂动态环境中容易陷入局部最优或规则冲突。Q-Learning通过"试错学习"机制,让机器人自主探索最优策略:
状态-动作-奖励闭环:机器人将当前环境感知(如激光雷达数据、邻居位置、目标方向)编码为状态 ss ,选择动作 aa (如前进、左转、右转、变速),执行后获得环境反馈的奖励 rr ,并转移到新状态 s’s ′。通过不断迭代更新Q值表 Q(s,a)Q(s,a) ,机器人逐渐学会在特定状态下选择能获得最大累积奖励的动作。
Bellman方程驱动学习:Q值更新遵循Bellman方程:
Q(s,a) \leftarrow Q(s,a) + \alpha \left[ r + \gamma \max_{a’} Q(s’,a’) - Q(s,a) \right]Q(s,a)←Q(s,a)+α[r+γ a ′maxQ(s ′ ,a ′)−Q(s,a)]
其中 \alphaα 为学习率, \gammaγ 为折扣因子,控制未来奖励的重要性。经过大量迭代,Q表收敛至最优策略。
探索与利用平衡:训练初期,机器人以较高概率随机探索( \epsilonϵ -greedy策略),避免陷入局部最优;随着学习深入,逐渐转向利用已学到的最优策略,实现从"盲目尝试"到"熟练执行"的平滑过渡。
模糊Q-Learning——解决维度灾难
传统Q-Learning面临"维度灾难"——当状态变量(如距离、角度、速度)连续且数量较多时,离散化后的状态空间指数级膨胀,Q表存储和计算开销不可接受。模糊Q-Learning通过模糊逻辑压缩状态空间:
连续状态模糊化:将连续的传感器数值(如距离0.5m、角度30°)映射为语言变量(如"距离近"隶属度0.7、“角度偏左"隶属度0.3),通过有限的模糊规则覆盖广阔的连续状态空间。
规则库压缩:例如定义规则"若距离近且角度偏左,则右转”,系统用少量规则即可表达复杂的状态-动作映射,大幅减少Q表规模,使其能在资源受限的Arduino平台上运行。
BLDC高动态执行——编队机动的物理基础
BLDC无刷电机配合FOC控制为Q-Learning策略的执行提供了关键支撑:
快速响应能力:BLDC电机的电磁时间常数远小于有刷电机,能够在毫秒级内响应Q-Learning输出的速度/转向指令,确保机器人在动态避障时动作敏捷。
差速转向与原地旋转:双向BLDC驱动支持左右轮独立控制,实现原地转向(Zero-turning)和差速转向,极大提升了在狭窄空间内的编队机动灵活性。
再生制动:减速或紧急制动时,BLDC工作于发电模式,将动能回馈至电池,提供强大的电磁制动效果,确保编队在高速运动中能快速停稳。
分层控制架构
决策层(Q-Learning):负责全局路径规划与避障决策。输入为激光雷达数据、邻居机器人位置、目标点方向;输出为期望的线速度和角速度。
执行层(BLDC FOC):负责将决策层的速度指令转化为电机PWM信号。通过PID闭环控制(电流环+速度环+位置环),确保电机精确跟踪期望速度。
通信层(ESP-NOW/ZigBee):负责多机器人之间的状态同步。各机器人通过低延迟无线通信协议实时共享自身位置、速度信息,为Q-Learning提供邻居状态输入。

二、典型应用场景
仓储物流多AGV协同
智能仓库中,数十台AGV小车需在狭窄通道内协同搬运货物,动态避让行人、叉车及其他AGV。
Q-Learning优势:传统规则方法在密集车流中容易死锁。Q-Learning通过与环境交互学习,能自主发现高效的避让策略(如主动让行、绕行),提升整体物流效率。
BLDC优势:高扭矩密度确保AGV在满载工况下仍能快速启停,满足仓储作业的高节拍要求。
特种作业协同搜救
地震废墟、火灾现场等非结构化环境中,多台搜救机器人需协同探索、动态避障并保持通信。
动态避障:废墟中障碍物位置不确定且可能移动(如坍塌物),Q-Learning能实时学习并适应动态环境,规划安全路径。
编队保持:在通信受限区域,机器人通过Q-Learning学习维持松散编队,确保信息共享和协同覆盖。
高校科研与算法验证
在RoboMaster、RoboCon等机器人竞赛或科研项目中,多机器人协同与强化学习是核心考点。
低成本验证平台:Arduino + BLDC + Q-Learning的组合成本低、开放性强,适合快速搭建多智能体实验平台,验证强化学习算法、编队控制策略。
算法对比:可在同一硬件平台上对比Q-Learning与传统方法(如人工势场法、DWA)的性能差异。
智能交通模拟
多台小车模拟智能网联汽车(ICV),在十字路口通过V2X通信实现无信号灯的自主避让与通行。
Q-Learning应用:每辆车作为独立智能体,通过Q-Learning学习最优通行策略(如让行、加速通过),验证交通流优化算法。

三、需要注意的事项
Arduino算力瓶颈是首要限制
Q-Learning涉及Q表查询、状态离散化、奖励计算等操作,对算力和内存要求较高。
平台选型:经典8位Arduino(如Uno,2KB SRAM)几乎无法胜任。必须选用ESP32-S3(双核240MHz,512KB SRAM)、STM32F4/H7或Arduino Portenta H7等高性能平台。
算法轻量化:使用模糊Q-Learning压缩状态空间;将Q表存储于外部Flash或SD卡;控制频率建议10~50Hz,平衡响应速度和计算负载。
主从架构:将Q-Learning训练放在上位机(如树莓派、PC),Arduino仅负责Q表查询和BLDC指令下发。
Q表维度灾难与收敛速度
Q-Learning的状态空间随变量数量指数级增长,导致Q表过大、收敛极慢。
状态离散化策略:对连续状态(如距离、角度)进行合理离散化,避免过细划分。例如,距离分为"近、中、远"三档,角度分为"左、中、右"三档。
函数近似:对于高维状态空间,使用神经网络拟合Q函数(即DQN),替代传统Q表。但DQN对算力要求更高,需配合GPU训练。
奖励函数设计:奖励函数直接影响学习效率和策略质量。需精心设计奖励项(如到达目标奖励、碰撞惩罚、平滑性奖励),避免稀疏奖励导致学习困难。
通信延迟与数据丢包
多机器人协同高度依赖实时的状态共享,通信延迟会导致策略失效。
低延迟协议:推荐使用ESP-NOW(毫秒级延迟)或ZigBee,避免使用Wi-Fi(延迟波动大)。
数据同步机制:各机器人需进行时间戳同步(如NTP协议),减少因时钟漂移导致的协同误差。
容错设计:当通信中断时,机器人应能基于最后已知状态继续执行安全策略(如减速停稳),避免碰撞。
BLDC控制精度与一致性
Q-Learning输出的速度指令需要BLDC电机精确执行,电机性能不一致会导致编队散乱。
电机一致性:同一编队中的所有BLDC电机应选用同批次产品,并精确测量电机参数(极对数、内阻、电感),写入FOC驱动板。
PID整定:FOC的电流环、速度环、位置环PID参数必须精细整定。速度环响应时间应<10ms,确保能忠实跟踪Q-Learning的高频指令。
编码器反馈:BLDC必须配备高分辨率编码器(如AS5600磁编码器),形成速度闭环。仅靠霍尔换相信号无法实现精确的速度控制。
奖励函数设计与训练稳定性
奖励函数是Q-Learning的"指挥棒",设计不当会导致策略偏离预期。
多目标权衡:奖励函数需综合考量到达目标(正奖励)、碰撞(负奖励)、能耗(负奖励)、平滑性(正奖励)等多个目标,通过权重调整实现动态权衡。
稀疏奖励问题:如果只有到达目标才有奖励,机器人可能长时间无法获得有效反馈。需引入中间奖励(如靠近目标奖励、远离障碍物奖励)引导学习。
训练稳定性:使用经验回放(Experience Replay)和目标网络(Target Network)技术,缓解Q-Learning的训练不稳定性。
电磁兼容(EMC)与电源管理
多BLDC电机同时运行会产生严重的电磁干扰和电流冲击。
电源隔离:BLDC动力电源(12V/24V)与Arduino逻辑电源(3.3V/5V)必须物理隔离,仅单点共地。使用独立DC-DC降压模块为逻辑电路供电。
电容滤波:ESC电源输入端并联大容量低ESR电解电容(1000μF~4700μF),吸收反向电动势和电流尖峰。
布线规范:强电(电机线、电池线)与弱电(信号线、传感器线)严格分开走线,最好呈90°垂直交叉。编码器、IMU等敏感信号线使用屏蔽线。

在这里插入图片描述
1、单机Q-Learning基础避障
这是最基础的单机器人避障实现,核心是将传感器数据离散化为状态,利用Q表选择动作。适合作为入门参照,帮你快速理解Q-Learning在嵌入式平台上的基本流程。

#include <Arduino.h>
#include <ELOQ.h> // 简化版Q-Learning库

#define STATE_SPACE 16  // 离散化状态空间(0~15)
#define ACTION_SPACE 5  // 动作空间:前进/后退/左转/右转/停止

Encoder enc(2, 3);      // 编码器用于测速
int speedPin = 9;
float currentSpeed = 0;

// Q-Learning参数:学习率0.9,折扣因子0.1,探索率0.8
ELOQ qlearning(STATE_SPACE, ACTION_SPACE, 0.9, 0.1, 0.8); 

void setup() {
  Serial.begin(115200);
  pinMode(speedPin, OUTPUT);
  qlearning.begin();
}

void loop() {
  // 1. 感知状态:将超声波距离映射为离散状态(0~15)
  int obstacleDist = analogRead(A0) / 10;  // 单位cm,0~100
  int state = floor(obstacleDist / 6.25);  // 离散化为16级

  // 2. Q-Learning决策(ε-greedy策略)
  int action = qlearning.chooseAction(state);

  // 3. 执行动作
  switch (action) {
    case 0: currentSpeed = 150; break;  // 前进
    case 1: currentSpeed = -100; break; // 后退
    case 2: // 左转(示例需补充具体实现)
    case 3: // 右转
    case 4: currentSpeed = 0; break;    // 停止
  }
  analogWrite(speedPin, constrain(abs(currentSpeed), 0, 255));

  // 4. 计算奖励
  float reward = 0;
  if (obstacleDist < 20) reward = -1;   // 碰撞惩罚
  else if (action == 0) reward = 0.1;   // 前进奖励

  // 5. Q表更新(下一状态简化处理)
  int newState = state; 
  qlearning.learn(state, action, reward, newState);

  // 6. 打印调试信息
  Serial.print("State: "); Serial.print(state);
  Serial.print(" Action: "); Serial.print(action);
  Serial.print(" Reward: "); Serial.println(reward);

  delay(200); // 控制学习频率
}

2、多机器人协同避障搬运
此案例引入了通信网络和分布式控制,多个机器人共享位置和障碍物信息,通过主从协同完成搬运任务。这比单机避障更接近实际机器人集群场景。

// 通信协议帧结构(NRF24L01)
typedef struct {
  uint8_t robot_id;
  float pos_x, pos_y;
  uint16_t obstacle_dist[8]; // 8方向障碍物距离
} RobotState;

// 协同控制主循环
void collaborativeControl() {
  if (isMaster) {
    broadcastPath();        // 广播全局路径
    receiveSlaveStates();   // 接收从机状态
    adjustPath();           // 根据反馈调整路径
  } else {
    sendState();            // 发送本机状态
    followPath();           // 执行路径跟踪
    avoidObstacles();       // 独立避障
  }
}

// 分布式自适应控制(每个机器人独立运行)
void distributedAdaptiveControl() {
  float local_error = target_speed - current_speed;
  adaptive_gain += 0.05 * local_error;  // 自适应增益调整
  motorPID->SetTunings(Kp * adaptive_gain, Ki, Kd);
  motorPID->Compute();
  setMotorTorque(target_torque);
}

3、三维状态Q-Learning避障
相比案例一的单一维度状态,这个版本将前、左、右三个方向的距离同时作为状态输入,决策依据更丰富,避障行为也更智能。

// 三维状态Q表:前方、左方、右方距离(每个维度离散化为10级)
float Q[10][10][10][4];  // 4个动作:前进/左转/右转/后退

void loop() {
  // 1. 读取三方向距离并离散化
  float dF = readCM(TRIG_F, ECHO_F);
  float dL = readCM(TRIG_L, ECHO_L);
  float dR = readCM(TRIG_R, ECHO_R);
  int sF = discretize(dF);  // 离散化为0~9
  int sL = discretize(dL);
  int sR = discretize(dR);

  // 2. ε-greedy选择动作
  Action action = selectAction(sF, sL, sR);

  // 3. 执行动作
  executeAction(action);

  // 4. 计算奖励(鼓励前进,惩罚靠近障碍物)
  float reward = getReward(dF, dL, dR, action);

  // 5. Q-Learning更新
  float maxQnext = -999;
  for(int a=0; a<ACTION_COUNT; a++) {
    if(Q[sF_new][sL_new][sR_new][a] > maxQnext)
      maxQnext = Q[sF_new][sL_new][sR_new][a];
  }
  Q[sF][sL][sR][action] += LEARNING_RATE * (
    reward + DISCOUNT_FACTOR * maxQnext - Q[sF][sL][sR][action]
  );

  // 6. 衰减探索率
  epsilon = max(EPSILON_MIN, epsilon * EPSILON_DECAY);
  
  delay(50);
}

要点解读

  1. 状态空间设计:避免维度灾难
    Q-Learning的表格式存储要求状态必须是离散且有限的。状态维度每增加一维,Q表大小呈指数增长(如案例三的三维状态表为 10×10×10×4=4000 个条目)。对于Arduino有限的RAM(通常仅2~8KB),建议状态维度≤20维,每维离散化级数控制在10以内。

  2. 奖励函数设计:引导正确行为
    奖励函数是Q-Learning的"指挥棒"。设计原则是:关键惩罚(碰撞)> 过程惩罚(偏离)> 正向奖励(前进)。常见策略是:碰撞时给大幅负奖励(如-10),接近障碍物时给小幅负惩罚,朝目标移动时给正向奖励。

  3. 探索与利用的平衡:ε-greedy策略
    机器人不能只"利用"已知经验,还需"探索"未知动作。典型做法是:初始探索率 ε=0.9(多探索),随着训练轮次增加,逐步衰减到0.1左右(多利用)。这种"先探索后利用"的策略能让Q表收敛到更优解。

  4. 控制周期与实时性
    控制周期需满足 T_c ≤ L / v_max(L为机器人尺寸,v_max为最大速度)。例如30cm的机器人以0.5m/s运动,理论周期需≤0.6s,实际建议控制在0.1s以内以保证响应及时。优化手段包括:禁用串口缓冲区、使用直接寄存器操作替代digitalWrite等。

  5. 硬件架构选择
    Uno/Nano:适合单机演示或极简场景,RAM限制大
    ESP32:内置WiFi/蓝牙,适合多机通信场景,算力更强
    STM32:可实现μs级控制周期,适合对实时性要求高的编队控制

在这里插入图片描述
4、双机器人基础动态避障编队(Q-Learning基础实现+固定目标编队)
适用场景:室内平坦场地(如教室、展厅),两台BLDC驱动机器人组成固定“并排编队”,需实时避开静态障碍(桌椅、立柱),保持编队形态的同时避免互相碰撞。

核心逻辑:每台机器人独立运行Q-Learning算法,定义“避障”“编队”“速度”三类状态,动作空间为{加速、减速、左转、右转};奖励函数同时惩罚“碰撞”“偏离编队”与“低效移动”,最终让机器人自主学习出“兼顾避障和编队保持”的最优策略,通过串口与队友交换位置信息,实现协同编队。

/* 双机器人基础动态避障编队:Q-Learning基础实现
   硬件:Arduino Mega ×2(每台配:BLDC电机2个、超声波传感器HC-SR04、IR定位模块、蓝牙模块)
   核心:独立Q-Learning+串口协同,状态=(避障距离,队友距离,速度),动作=(加/减/左/右)
   参数:Q表容量50×4、探索率ε=0.9、学习率α=0.1、折扣因子γ=0.8、奖励:避障+10、编队+5、碰撞-50、脱离-20
*/
#include <SimpleFOC.h>
#include <SoftwareSerial.h>

// --- 核心参数定义 ---
#define STATE_COUNT 50    // Q表状态容量(避障距离×队友距离×速度分级)
#define ACTION_COUNT 4    // 动作:0=加速,1=减速,2=左转,3=右转
#define EPSILON 0.9       // 探索率(初始多探索,后期多利用)
#define ALPHA 0.1         // 学习率(更新幅度)
#define GAMMA 0.8         // 折扣因子(未来奖励权重)
#define SAFE_DIST 150     // 避障安全距离(mm)
#define BASE_FORMATION 200// 编队目标距离(mm,两机器人横向间距)

// --- 硬件接口定义 ---
BLDCMotor motorL, motorR;
#define MOTOR_L_DRIVER 9,10,11  // 左电机驱动引脚
#define MOTOR_R_DRIVER 12,13,14  // 右电机驱动引脚
#define TRIG_PIN 2               // 超声波触发脚
#define ECHO_PIN 3               // 超声波接收脚
#define IR_PIN 4                 // IR队友定位传感器
SoftwareSerial BT(5,6);          // 蓝牙串口(与队友通信)

// --- Q-Learning核心数据结构 ---
int qTable[STATE_COUNT][ACTION_COUNT] = {0}; // 二维Q表
int currentState = 0;            // 当前状态索引
int currentAction = 0;           // 当前动作索引
long lastLearnTime = 0;          // 上次学习时间
const long LEARN_INTERVAL = 100; // 学习间隔(ms)

// --- 全局变量 ---
float obstacleDist = 0;          // 障碍距离(超声波测得)
float teammateDist = 0;          // 队友距离(IR+蓝牙协同)
float currentSpeed = 0.1;        // 当前速度(m/s)
float lastObstacleDist = 0;      // 上一周期障碍距离
float lastTeammateDist = 0;      // 上一周期队友距离
int reward = 0;                  // 即时奖励

void setup() {
  Serial.begin(115200);
  BT.begin(9600);
  initMotors();
  initSensors();
  randomSeed(analogRead(0)); // 随机种子初始化
  Serial.println("双机器人:Q-Learning避障编队启动");
}

void loop() {
  // 1. 感知环境:获取障碍、队友距离、速度
  updateSensors();
  // 2. 状态编码:将连续数据离散为状态索引
  currentState = encodeState(obstacleDist, teammateDist, currentSpeed);
  // 3. 决策动作:ε-贪心选择(探索/利用)
  if (random(100) < EPSILON * 100) {
    currentAction = random(ACTION_COUNT); // 探索:随机选动作
  } else {
    currentAction = selectBestAction(currentState); // 利用:选Q值最高动作
  }
  // 4. 执行动作:驱动BLDC电机
  executeAction(currentAction);
  // 5. 计算奖励:根据避障、编队、碰撞情况打分
  calculateReward();
  // 6. Q-Learning更新:迭代优化Q表
  if (millis() - lastLearnTime >= LEARN_INTERVAL) {
    updateQTable();
    lastLearnTime = millis();
  }
  // 7. 串口协同:发送自身位置,接收队友数据
  sendTeammateData();
  receiveTeammateData();
  delay(50); // 控制周期50ms,兼顾实时性与算力
}

// 初始化BLDC电机
void initMotors() {
  motorL.linkDriver(new BLDCDriver3PWM(9,10,11));
  motorR.linkDriver(new BLDCDriver3PWM(12,13,14));
  motorL.linkSensor(new Encoder(15,16));
  motorR.linkSensor(new Encoder(17,18));
  motorL.controller = MotionControlType::velocity;
  motorR.controller = MotionControlType::velocity;
  motorL.init();
  motorR.init();
  motorL.initFOC();
  motorR.initFOC();
  motorL.target = 0.1;
  motorR.target = 0.1;
}

// 初始化传感器
void initSensors() {
  pinMode(TRIG_PIN, OUTPUT);
  pinMode(ECHO_PIN, INPUT);
  pinMode(IR_PIN, INPUT);
}

// 更新传感器数据
void updateSensors() {
  // 超声波测障碍距离
  digitalWrite(TRIG_PIN, LOW); delayMicroseconds(2);
  digitalWrite(TRIG_PIN, HIGH); delayMicroseconds(10);
  digitalWrite(TRIG_PIN, LOW);
  obstacleDist = pulseIn(ECHO_PIN, HIGH) / 58.0; // 转换为mm
  lastObstacleDist = obstacleDist;

  // IR测队友距离(简化:通过模拟值估算距离,0-1023对应0-500mm)
  teammateDist = analogRead(IR_PIN) * 0.5;
  lastTeammateDist = teammateDist;
}

// 状态编码:将连续变量离散为0~STATE_COUNT-1的索引
int encodeState(float obs, float team, float speed) {
  // 避障距离分3级:近(<100mm)、中(100-200mm)、远(>200mm)
  int obsLevel = (obs < 100) ? 0 : ((obs < 200) ? 1 : 2);
  // 队友距离分3级:远(>250mm)、中(150-250mm)、近(<150mm)
  int teamLevel = (team > 250) ? 0 : ((team > 150) ? 1 : 2);
  // 速度分2级:慢(≤0.15m/s)、快(>0.15m/s)
  int speedLevel = (speed <= 0.15) ? 0 : 1;
  // 组合状态:obsLevel×(3×2) + teamLevel×2 + speedLevel
  return obsLevel * 6 + teamLevel * 2 + speedLevel;
}

// 选择Q值最高的动作(贪心策略)
int selectBestAction(int state) {
  int maxQ = -1000;
  int bestAction = 0;
  for (int a = 0; a < ACTION_COUNT; a++) {
    if (qTable[state][a] > maxQ) {
      maxQ = qTable[state][a];
      bestAction = a;
    }
  }
  return bestAction;
}

// 执行动作:驱动BLDC电机(差速转向+速度调整)
void executeAction(int action) {
  switch (action) {
    case 0: // 加速:双电机加速
      motorL.target = 0.2;
      motorR.target = 0.2;
      currentSpeed = 0.2;
      break;
    case 1: // 减速:双电机减速
      motorL.target = 0.05;
      motorR.target = 0.05;
      currentSpeed = 0.05;
      break;
    case 2: // 左转:左电机减速,右电机加速
      motorL.target = 0.05;
      motorR.target = 0.2;
      currentSpeed = (0.05 + 0.2) / 2;
      break;
    case 3: // 右转:左电机加速,右电机减速
      motorL.target = 0.2;
      motorR.target = 0.05;
      currentSpeed = (0.2 + 0.05) / 2;
      break;
  }
  motorL.loopFOC();
  motorR.loopFOC();
}

// 计算奖励函数:避障、编队、碰撞、效率综合打分
void calculateReward() {
  reward = 0;
  // 1. 避障奖励:距离越远奖励越高,低于安全距离扣分
  if (obstacleDist > SAFE_DIST) reward += 10 + (obstacleDist - SAFE_DIST) * 0.05;
  else if (obstacleDist < 50) reward -= 50; // 碰撞危险,大幅扣分
  else reward -= (SAFE_DIST - obstacleDist) * 0.2;

  // 2. 编队奖励:距离符合目标,奖励;偏离过大扣分
  if (teammateDist > BASE_FORMATION - 30 && teammateDist < BASE_FORMATION + 30)
    reward += 5;
  else reward -= abs(teammateDist - BASE_FORMATION) * 0.1;

  // 3. 效率奖励:避免频繁加减速,保持稳定速度
  if (abs(currentSpeed - 0.15) < 0.02) reward += 2;
  else reward -= abs(currentSpeed - 0.15) * 0.5;
}

// Q-Learning更新:迭代优化Q表
void updateQTable() {
  // 下一状态编码
  int nextState = encodeState(obstacleDist, teammateDist, currentSpeed);
  // 下一动作:选择下一状态Q值最高的动作
  int nextAction = selectBestAction(nextState);
  // Q-Learning更新公式:Q(s,a) = Q(s,a) + α*(r + γ*maxQ(s',a') - Q(s,a))
  int qCurrent = qTable[currentState][currentAction];
  int qNextMax = qTable[nextState][nextAction];
  qTable[currentState][currentAction] = qCurrent + ALPHA * (reward + GAMMA * qNextMax - qCurrent);
}

// 串口协同:发送自身位置数据
void sendTeammateData() {
  // 模拟发送:自身障碍距离+队友距离+当前速度,格式:OBS,TEAM,SPEED
  BT.print("OBS,");
  BT.print(obstacleDist);
  BT.print(",TEAM,");
  BT.print(teammateDist);
  BT.print(",SPEED,");
  BT.print(currentSpeed);
  BT.println();
}

// 串口协同:接收队友数据
void receiveTeammateData() {
  if (BT.available()) {
    String data = BT.readStringUntil('\n');
    int comma1 = data.indexOf(',');
    int comma2 = data.indexOf(',', comma1+1);
    int comma3 = data.indexOf(',', comma2+1);
    // 解析队友的障碍距离、自身与队友的距离、速度
    float teamObs = data.substring(0, comma1).toFloat();
    teammateDist = data.substring(comma1+4, comma2).toFloat();
    if (comma3 != -1) {
      currentSpeed = data.substring(comma3+6).toFloat();
    }
  }
}

5、多机器人动态协同避障编队(状态共享+团队奖励强化)
适用场景:仓储物流场景,4台BLDC机器人组成“跟随编队”(前导+3跟随),需避开动态障碍(如移动的叉车、工作人员),同时保持编队不脱节、不碰撞,核心是团队协同而非个体独立决策。

核心逻辑:引入“状态共享机制”,通过无线串口组建多机通信网络,前导机器人主动广播自身位置与障碍信息,跟随机器人接收信息后,将“队友状态”纳入自身Q-Learning状态空间;奖励函数加入团队目标奖励,避免个体只顾自身避障导致编队混乱,通过集中式团队奖励+分布式个体决策,实现协同避障编队。

/* 多机器人动态协同避障编队:状态共享+团队奖励
   硬件:Arduino Mega ×4(1台前导+3台跟随,每台配:BLDC双电机、超声波、蓝牙模块)
   核心:前导广播状态,跟随共享信息,状态=(自身障碍,队友距离,编队角色),团队奖励联动
   参数:编队角色3种(前导/跟随1/跟随2)、Q表容量80×4、团队奖励系数0.6,个体奖励0.4
*/
#include <SimpleFOC.h>
#include <SoftwareSerial.h>

// --- 编队与学习参数 ---
#define ROBOT_COUNT 4
#define ROBOT_ROLE 3  // 角色:0=前导,1=跟随1,2=跟随2
int currentRole = 0;   // 当前机器人角色(手动设定,前导=0,跟随依次为1、2、3)
#define STATE_COUNT 80
#define ACTION_COUNT 4
#define EPSILON 0.85
#define ALPHA 0.12
#define GAMMA 0.85
#define TEAM_REWARD_COEFF 0.6 // 团队奖励占比,个体奖励占0.4

// --- 硬件与通信 ---
BLDCMotor motorL, motorR;
#define MOTOR_L_DRIVER 9,10,11
#define MOTOR_R_DRIVER 12,13,14
#define TRIG_PIN 2
#define ECHO_PIN 3
SoftwareSerial BT(5,6);

// --- Q表与团队状态 ---
int qTable[STATE_COUNT][ACTION_COUNT] = {0};
int currentState = 0;
int currentAction = 0;
long lastLearnTime = 0;
const long LEARN_INTERVAL = 150;

// --- 多机器人共享状态 ---
float allObstacleDists[ROBOT_COUNT] = {0}; // 所有机器人的障碍距离
float allTeammateDists[ROBOT_COUNT][ROBOT_COUNT] = {0}; // 机器人i与机器人j的距离
int teamFormationStatus = 1; // 团队编队状态:1=正常,0=混乱
float teamSpeed = 0.15; // 团队平均速度

void setup() {
  Serial.begin(115200);
  BT.begin(9600);
  initMotors();
  initSensors();
  randomSeed(analogRead(0));
  Serial.print("多机器人协同编队启动,当前角色:");
  Serial.println(currentRole == 0 ? "前导" : "跟随");
}

void loop() {
  if (currentRole == 0) {
    runLeaderRole(); // 前导机器人逻辑
  } else {
    runFollowerRole(); // 跟随机器人逻辑
  }
  delay(60);
}

// 前导机器人核心逻辑:感知+广播+决策
void runLeaderRole() {
  // 1. 感知自身障碍
  float obs = getObstacleDistance();
  allObstacleDists[0] = obs;
  // 2. 决策:基于自身Q表选择动作
  currentState = encodeLeaderState(obs, teamSpeed);
  currentAction = (random(100) < EPSILON*100) ? random(ACTION_COUNT) : selectBestAction(currentState);
  executeAction(currentAction);
  // 3. 计算团队奖励:以整体编队完成度为标准
  int teamReward = calculateTeamReward();
  // 4. 更新自身Q表(团队奖励权重0.6)
  if (millis() - lastLearnTime >= LEARN_INTERVAL) {
    int nextState = encodeLeaderState(obs, currentSpeed);
    int nextAction = selectBestAction(nextState);
    int qCurrent = qTable[currentState][currentAction];
    qTable[currentState][currentAction] = qCurrent + ALPHA * (
      TEAM_REWARD_COEFF * teamReward + (1-TEAM_REWARD_COEFF) * getLeaderIndividualReward(obs)
      + GAMMA * qTable[nextState][nextAction] - qCurrent
    );
    lastLearnTime = millis();
  }
  // 5. 广播自身状态与团队信息
  broadcastTeamState(obs, currentSpeed, teamFormationStatus);
}

// 跟随机器人核心逻辑:接收广播+共享信息+决策
void runFollowerRole() {
  // 1. 接收前导与其他跟随机器人的广播数据
  receiveTeamState();
  // 2. 感知自身障碍与队友距离
  float obs = getObstacleDistance();
  float teammateDist = getTeammateDistance(); // 获取与前导的距离
  allObstacleDists[currentRole] = obs;
  // 3. 决策:将团队共享状态纳入自身Q表
  currentState = encodeFollowerState(obs, teammateDist, currentRole);
  currentAction = (random(100) < EPSILON*100) ? random(ACTION_COUNT) : selectBestAction(currentState);
  executeAction(currentAction);
  // 4. 计算团队与个体奖励
  int teamReward = calculateTeamReward();
  int individualReward = getFollowerIndividualReward(obs, teammateDist);
  // 5. 更新Q表
  if (millis() - lastLearnTime >= LEARN_INTERVAL) {
    int nextState = encodeFollowerState(obs, teammateDist, currentRole);
    int nextAction = selectBestAction(nextState);
    int qCurrent = qTable[currentState][currentAction];
    qTable[currentState][currentAction] = qCurrent + ALPHA * (
      TEAM_REWARD_COEFF * teamReward + (1-TEAM_REWARD_COEFF) * individualReward
      + GAMMA * qTable[nextState][nextAction] - qCurrent
    );
    lastLearnTime = millis();
  }
  // 6. 转发团队状态,辅助通信
  forwardTeamState();
}

// 前导状态编码:障碍+团队平均速度
int encodeLeaderState(float obs, float speed) {
  int obsLevel = (obs < 80) ? 0 : ((obs < 160) ? 1 : 2);
  int speedLevel = (speed < 0.12) ? 0 : ((speed < 0.2) ? 1 : 2);
  int roleLevel = 0; // 前导角色编码0
  return obsLevel * 6 + speedLevel * 2 + roleLevel;
}

// 跟随状态编码:障碍+队友距离+角色(区分跟随顺序)
int encodeFollowerState(float obs, float teammate, int role) {
  int obsLevel = (obs < 80) ? 0 : ((obs < 160) ? 1 : 2);
  int teammateLevel = (teammate < 120) ? 0 : ((teammate < 200) ? 1 : 2);
  int roleLevel = role - 1; // 跟随角色编码1/2(跟随1=1,跟随2=2)
  return obsLevel * 6 + teammateLevel * 2 + roleLevel;
}

// 团队奖励计算:根据整体编队、避障效率打分
int calculateTeamReward() {
  int reward = 0;
  // 1. 编队状态:所有机器人保持合理间距,奖励
  bool formationOk = true;
  for (int i = 0; i < ROBOT_COUNT; i++) {
    for (int j = 0; j < ROBOT_COUNT; j++) {
      if (i != j && (allTeammateDists[i][j] < 60 || allTeammateDists[i][j] > 300)) {
        formationOk = false;
        break;
      }
    }
    if (!formationOk) break;
  }
  if (formationOk) reward += 50;
  else reward -= 30;

  // 2. 避障整体情况:无机器人碰撞,奖励
  bool noCollision = true;
  for (int i = 0; i < ROBOT_COUNT; i++) {
    if (allObstacleDists[i] < 50) {
      noCollision = false;
      break;
    }
  }
  if (noCollision) reward += 30;
  else reward -= 80;

  // 3. 速度一致性:团队速度稳定,奖励
  if (abs(teamSpeed - 0.15) < 0.03) reward += 20;
  else reward -= 10;

  return reward;
}

// 广播团队状态:前导主动发送
void broadcastTeamState(float obs, float speed, int formation) {
  BT.print("LEADER,");
  BT.print(currentRole);
  BT.print(",OBS,");
  BT.print(obs);
  BT.print(",SPEED,");
  BT.print(speed);
  BT.print(",FORM,");
  BT.println(formation);
}

// 接收团队状态:跟随机器人接收并解析
void receiveTeamState() {
  if (BT.available()) {
    String data = BT.readStringUntil('\n');
    int idx1 = data.indexOf(',');
    int idx2 = data.indexOf(',', idx1+1);
    int idx3 = data.indexOf(',', idx2+1);
    int idx4 = data.indexOf(',', idx3+1);
    int idx5 = data.indexOf(',', idx4+1);
    int idx6 = data.indexOf(',', idx5+1);

    int senderRole = data.substring(idx1+1, idx2).toInt();
    float obs = data.substring(idx2+4, idx3).toFloat();
    float speed = data.substring(idx3+6, idx4).toFloat();
    int formation = data.substring(idx5+4).toInt();

    // 更新共享状态数组
    allObstacleDists[senderRole] = obs;
    allTeammateDists[currentRole][senderRole] = obs; // 简化:以障碍替代距离,实际需独立测距
    teamSpeed = speed;
    teamFormationStatus = formation;
  }
}

// 其余硬件驱动、动作执行、Q表选择等函数与案例1类似,此处省略以突出核心协同逻辑
// 注:实际代码需补充电机初始化、超声波测距、动作执行等基础函数,与案例1保持一致

6、复杂对抗场景下的动态避障编队(对手建模+对抗Q-Learning)
适用场景:对抗训练或复杂竞赛场景,两台机器人组成攻防编队,需避开对手的主动干扰,同时保持自身编队不被破坏,核心是应对动态对抗目标(对手会主动破坏编队或制造障碍)。

核心逻辑:引入“对手状态建模”,将对手的动作趋势纳入自身Q-Learning状态空间;采用“对抗Q-Learning”,在Q表更新时考虑对手可能的最优动作,奖励函数加入“对抗成功”“编队保持”“对抗失败”三类核心指标,让机器人从被动避障转变为主动对抗性编队调整。

/* 复杂对抗场景动态避障编队:对手建模+对抗Q-Learning
   硬件:Arduino Mega ×2(攻防机器人,每台配:BLDC双电机、超声波、简易视觉追踪、无线模块)
   核心:对手状态建模,状态=(自身障碍,对手距离,对手动作趋势),对抗奖励(成功+100,失败-100)
   参数:对手动作趋势3种(进攻/后退/侧移)、Q表容量60×4、对抗奖励权重0.7,编队奖励0.3
*/
#include <SimpleFOC.h>
#include <SoftwareSerial.h>

// --- 对抗与学习参数 ---
#define OPPONENT_TREND 3  // 对手动作趋势:0=进攻,1=后退,2=侧移
#define STATE_COUNT 60
#define ACTION_COUNT 5    // 动作:0=加速,1=减速,2=左转,3=右转,4=编队调整
#define EPSILON 0.8
#define ALPHA 0.1
#define GAMMA 0.85
#define OPPONENT_REWARD_COEFF 0.7

// --- 硬件与通信 ---
BLDCMotor motorL, motorR;
#define MOTOR_L_DRIVER 9,10,11
#define MOTOR_R_DRIVER 12,13,14
#define TRIG_PIN 2
#define ECHO_PIN 3
#define VISUAL_PIN 4  // 简易视觉追踪传感器(模拟输入,识别对手位置)
SoftwareSerial RF(5,6); // 无线通信,接收对手状态

// --- Q表与对抗状态 ---
int qTable[STATE_COUNT][ACTION_COUNT] = {0};
int currentState = 0;
int currentAction = 0;
long lastLearnTime = 0;
const long LEARN_INTERVAL = 120;

// --- 对手状态建模 ---
float opponentDist = 0;
int opponentAction = -1; // 对手上周期动作:-1=未知,0-4=动作编码
int opponentTrend = 0;   // 对手动作趋势:0=进攻,1=后退,2=侧移
float myTeammateDist = 0; // 自身与队友的距离(编队指标)

void setup() {
  Serial.begin(115200);
  RF.begin(9600);
  initMotors();
  initSensors();
  randomSeed(analogRead(0));
  Serial.println("对抗场景编队:对抗Q-Learning启动");
}

void loop() {
  // 1. 感知:自身障碍、对手距离与趋势、队友距离
  updateAdversarialState();
  // 2. 状态编码:融入对手动作趋势
  currentState = encodeAdversarialState(obstacleDist, opponentDist, opponentTrend, myTeammateDist);
  // 3. 对抗决策:考虑对手可能的动作,选择最优策略
  currentAction = selectAdversarialAction(currentState);
  // 4. 执行动作:兼顾避障、对抗、编队调整
  executeAdversarialAction(currentAction);
  // 5. 计算对抗奖励:以对抗结果为核心
  int reward = calculateAdversarialReward();
  // 6. Q表更新:针对对抗场景优化
  if (millis() - lastLearnTime >= LEARN_INTERVAL) {
    updateAdversarialQTable();
    lastLearnTime = millis();
  }
  // 7. 无线协同:发送自身状态,接收对手信息
  sendAdversarialState();
  receiveOpponentState();
  delay(60);
}

// 更新对抗状态:感知自身、对手、队友
void updateAdversarialState() {
  // 自身障碍
  obstacleDist = getObstacleDistance();
  // 队友距离(保持编队)
  myTeammateDist = analogRead(VISUAL_PIN) * 0.3; // 视觉识别队友,估算距离
  // 对手状态通过无线接收,本地更新趋势
  if (opponentAction != -1) {
    // 分析对手动作趋势:连续进攻=进攻,连续远离=后退,左右移动频繁=侧移
    if (opponentAction == 0 && lastOpponentAction == 0) opponentTrend = 0;
    else if (opponentAction == 1 && lastOpponentAction == 1) opponentTrend = 1;
    else if (abs(opponentAction - lastOpponentAction) == 2) opponentTrend = 2;
    lastOpponentAction = opponentAction;
  }
}

// 对抗状态编码:融入对手趋势
int encodeAdversarialState(float obs, float opp, int trend, float teammate) {
  int obsLevel = (obs < 70) ? 0 : ((obs < 140) ? 1 : 2);
  int oppLevel = (opp < 100) ? 0 : ((opp < 200) ? 1 : 2);
  int trendLevel = trend; // 对手趋势直接作为状态分量
  int teammateLevel = (teammate < 150) ? 0 : ((teammate < 250) ? 1 : 2);
  return obsLevel * 6 + oppLevel * 2 + trendLevel + teammateLevel * 3 * 3;
}

// 对抗动作选择:结合Q表与对手趋势,优先选择克制对手的动作
int selectAdversarialAction(int state) {
  // 基础:ε-贪心选择
  if (random(100) < EPSILON * 100) {
    return random(ACTION_COUNT);
  }

  // 对抗优化:根据对手趋势,调整动作优先级
  int baseAction = selectBestAction(state);
  // 对手进攻趋势:优先选择减速+侧移(动作2或3),避免正面碰撞
  if (opponentTrend == 0) {
    if (baseAction == 0) return 3; // 原加速,改为右转避让
    if (baseAction == 1) return 2; // 原减速,改为左转,保持距离
  }
  // 对手后退趋势:优先选择加速,扩大优势
  if (opponentTrend == 1 && baseAction == 0) return 0;
  // 对手侧移趋势:优先选择同方向侧移,保持对抗姿态
  if (opponentTrend == 2) {
    if (baseAction == 2) return 2;
    if (baseAction == 3) return 3;
  }
  // 其余情况按基础最优动作执行
  return baseAction;
}

// 执行对抗动作:动作4为编队调整(特殊对抗动作)
void executeAdversarialAction(int action) {
  switch (action) {
    case 0: motorL.target = 0.2; motorR.target = 0.2; break;
    case 1: motorL.target = 0.05; motorR.target = 0.05; break;
    case 2: motorL.target = 0.05; motorR.target = 0.2; break;
    case 3: motorL.target = 0.2; motorR.target = 0.05; break;
    case 4: // 编队调整:前后错位,避免对手破坏编队
      motorL.target = 0.15; motorR.target = 0.18; // 轻微差速,调整自身位置
      break;
  }
  currentSpeed = (motorL.target + motorR.target) / 2;
  motorL.loopFOC();
  motorR.loopFOC();
}

// 计算对抗奖励:对抗结果为核心,兼顾避障与编队
int calculateAdversarialReward() {
  int reward = 0;
  // 1. 对抗核心:对手距离越远且自身未受损,奖励;被对手逼近,扣分
  if (opponentDist > 200) reward += 100;
  else if (opponentDist < 80) reward -= 100;
  else reward += (opponentDist - 80) * 0.5;

  // 2. 避障:不碰撞,奖励;碰撞,大幅扣分
  if (obstacleDist > 100) reward += 30;
  else if (obstacleDist < 50) reward -= 80;

  // 3. 编队:保持与队友合理距离,奖励;被对手冲散,扣分
  if (myTeammateDist > 150 && myTeammateDist < 250) reward += 40;
  else if (myTeammateDist > 300 || myTeammateDist < 100) reward -= 50;

  return reward;
}

// 对抗Q表更新:考虑对手可能的动作对自身策略的影响
void updateAdversarialQTable() {
  int nextState = encodeAdversarialState(obstacleDist, opponentDist, opponentTrend, myTeammateDist);
  int nextAction = selectAdversarialAction(nextState);
  // 预测对手下一动作,调整折扣因子
  int predictedOpponentAction = predictOpponentAction();
  // 若对手可能采取干扰动作,降低未来奖励权重(更注重当前对抗结果)
  int adjustedGamma = (predictedOpponentAction == 0 || predictedOpponentAction == 2) ? (int)(GAMMA * 0.7) : GAMMA;

  int qCurrent = qTable[currentState][currentAction];
  qTable[currentState][currentAction] = qCurrent + ALPHA * (reward + adjustedGamma * qTable[nextState][nextAction] - qCurrent);
}

// 预测对手下一动作(简化:基于趋势预测)
int predictOpponentAction() {
  if (opponentTrend == 0) return 0; // 进攻趋势,预测进攻
  if (opponentTrend == 1) return 1; // 后退趋势,预测后退
  return 2; // 侧移趋势,预测侧移
}

// 发送自身对抗状态
void sendAdversarialState() {
  RF.print("ROLE,1,OBS,");
  RF.print(obstacleDist);
  RF.print(",OPPDIST,");
  RF.print(opponentDist);
  RF.print(",ACTION,");
  RF.print(currentAction);
  RF.println();
}

// 接收对手状态
void receiveOpponentState() {
  if (RF.available()) {
    String data = RF.readStringUntil('\n');
    int idx1 = data.indexOf(',');
    int idx2 = data.indexOf(',', idx1+1);
    int idx3 = data.indexOf(',', idx2+1);
    int idx4 = data.indexOf(',', idx3+1);
    int idx5 = data.indexOf(',', idx4+1);

    int oppAction = data.substring(idx4+6, idx5).toInt();
    opponentDist = data.substring(idx2+6, idx3).toFloat();
    opponentAction = oppAction;
  }
}

// 其余硬件驱动函数与前两个案例保持一致,此处省略

要点解读

  1. 状态空间的精简设计:平衡感知维度与算力约束
    Arduino的核心瓶颈是算力与存储(RAM/Flash有限),Q-Learning的状态空间必须在“全面感知”与“落地可行”间找到平衡,这是工程落地的核心前提:
    状态维度聚焦核心目标:围绕“避障+编队+环境”三大核心,剔除冗余感知(如复杂地形、无关障碍物),案例4仅用“避障距离+队友距离+速度”3类连续变量,离散化为50个状态;案例5加入“编队角色”维度,案例3加入“对手动作趋势”,始终聚焦与决策强相关的维度,避免状态爆炸。
    离散化策略适配硬件能力:将连续的传感器数据(距离、速度)转化为有限的离散等级(如3级/2级),大幅压缩Q表大小(从连续空间的无限可能压缩到几十到几百个状态),适配Arduino的存储限制。
    状态编码的唯一性与无歧义性:通过状态分量的权重组合(如obsLevel6 + teamLevel2 + speedLevel)确保不同环境数据对应唯一的状态索引,避免同一环境被编码为多个状态,导致Q表学习效率低下。
  2. 奖励函数的多目标优化:强化学习的学习“指挥棒”
    Q-Learning的本质是“通过奖励信号引导策略优化”,奖励函数的设计直接决定机器人是否能够学习到符合预期的行为(避障+编队兼顾),核心是解决多目标冲突(避障与编队可能相互制约):
    多目标权重平衡:将“避障(安全)、编队(协同)、效率(速度)”三类目标赋予不同权重,案例4采用“避障奖励高权重、编队中等权重、效率辅助权重”的分配,避免机器人只顾避障而脱离编队,或只顾编队而碰撞障碍。
    正负反馈结合,突出核心约束:对核心风险(碰撞、编队崩溃)设置高惩罚(负奖励),对核心目标(安全避障、保持编队)设置正奖励,案例6对“对抗失败”设-100高惩罚,“对抗成功”设+100高奖励,强化学习的效率远高于仅用正奖励引导。
    动态奖励调整适配场景:不同场景对目标的优先级不同,基础场景突出编队稳定性,对抗场景突出对抗效果,案例5引入团队奖励机制,占比60%,迫使机器人优先保障团队整体目标,而非个体局部最优,解决多机器人协同的“局部最优陷阱”。
  3. 探索-利用的动态平衡:解决学习收敛与实时决策的矛盾
    Q-Learning的核心矛盾是“探索未知(尝试新动作,积累经验)”与“利用已知(选择最优动作,保证当下表现)”,Arduino的实时性要求决策不能过度探索,需动态平衡:
    ε-贪心策略的场景适配:初始阶段设置高探索率,让机器人充分尝试各种动作,积累Q表;随着学习迭代逐步降低探索率,转向利用最优策略。案例1的探索率从0.9逐步衰减到0.6,兼顾初期学习与后期稳定决策;对抗场景保留较高探索率,避免被对手预测动作,保持对抗灵活性。
    探索与利用的周期化切换:采用“周期性探索”机制,避免探索率无限降低导致的策略固化,案例6在对抗场景中,每隔一定周期强制探索1-2个随机动作,维持对对手动作变化的感知能力,避免策略被对手适应。
    实时性约束下的探索限制:Arduino的控制周期短(50-100ms),探索动作不能过多,否则会导致控制不稳定,案例1将探索动作限制为单个,避免多动作同时探索导致电机频繁切换,保证驱动系统稳定。
  4. 分布式决策与协同机制:多机器人编队的核心纽带
    多机器人动态避障编队的核心是“个体决策+群体协同”,既不能依赖集中式控制(Arduino算力不支持、通信延迟高),也不能完全分布式决策(易导致冲突),核心是建立高效的轻量化协同机制:
    轻量化状态共享协议:采用精简的串口数据格式,仅传输核心状态(障碍距离、位置、速度),避免传输冗余数据,案例2的广播格式仅包含角色、障碍、速度、编队状态,字节数少,通信延迟低,适配Arduino的串口带宽。
    角色化分布式决策:明确前导与跟随的角色分工,前导负责全局感知与策略引导,跟随负责局部感知与状态跟随,降低决策复杂度。前导机器人不依赖跟随机器人的状态即可决策,跟随机器人根据前导状态调整策略,实现“全局引导+局部适应”的协同模式,避免集中式控制的压力。
    协同容错与重传机制:Arduino通信易受干扰,采用简单的校验机制与超时重传,案例2在数据传输末尾加入状态校验位,若接收方发现校验错误,忽略当前数据并等待下一次广播,避免错误数据导致错误决策,提升协同可靠性。
  5. 嵌入式资源的极致优化:保障Q-Learning在Arduino上落地
    Q-Learning在资源丰富的平台上实现简单,但在Arduino这类低算力、小存储的平台上,必须通过极致的资源优化才能落地,这是工程化的核心难点:
    Q表的存储与访问优化:采用二维数组存储Q表,避免动态内存分配(malloc在Arduino上易导致内存碎片化),案例1的50×4Q表仅占200字节,案例5的80×4仅占320字节,完全适配Arduino的RAM;访问时采用直接索引方式,避免循环查找,提升决策速度。
    算法的轻量化裁剪:简化Q-Learning的更新逻辑,省略复杂的函数调用与浮点数运算(除必要外),用整数近似浮点数运算,案例1的Q值更新用整数存储,学习率、折扣因子用整数缩放,降低算力消耗;取消复杂的探索策略,采用简单的随机探索,适配Arduino的运算能力。
    控制周期与学习周期解耦:将环境感知、动作执行的“控制周期”(50ms)与Q表学习的“学习周期”(100-150ms)分离,控制周期优先保障电机实时响应,学习周期在后台更新Q表,避免学习过程占用控制周期,保证机器人运动的稳定性,解决实时控制与学习的算力冲突。

请注意:以上案例仅作为思路拓展的参考示例,不保证完全正确、适配所有场景或可直接编译运行。由于硬件平台、实际使用场景、Arduino 版本的差异,均可能影响代码的适配性与使用方法的选择。在实际编程开发时,请务必根据自身硬件配置、使用场景及具体功能需求进行针对性调整,并通过多次实测验证效果;同时需确保硬件接线正确,充分了解所用传感器、执行器等设备的技术规范与核心特性。对于涉及硬件操作的代码,使用前务必核对引脚定义、电平参数等关键信息的准确性与安全性,避免因参数错误导致硬件损坏或运行异常。

在这里插入图片描述

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐