You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Webots机器人控制器修改Vector值时崩溃问题求助

Webots模拟器控制器崩溃问题排查与修复

运行Webots模拟器时,主机器人控制器在0.750秒时冻结崩溃,调试确认问题出在vector赋值相关代码段,注释后程序可正常运行。以下是代码中的问题点及修复方案:


核心问题分析

  1. 逗号表达式误用导致数值计算错误
    代码中input2 = (right1->getVelocity(), right2->getVelocity(), right3->getVelocity()) / 3;使用了逗号表达式,这只会返回最后一个right3->getVelocity()的值,而非三个速度的平均值,会导致后续网络输入异常。

  2. State向量未完全赋值
    state.resize(3)后仅给state[0]赋值,state[1]和state[2]未初始化(默认值为0),但actor网络要求3维输入,这会引发网络计算的潜在内存问题。

  3. Values向量重复添加元素引发越界
    连续执行两次values.push_back(valueEstimates[0][0]);,导致values长度是logProbs、rewards等向量的两倍。后续计算优势函数时,访问values[t+1]会触发数组越界,这是控制器崩溃的核心原因。

  4. Critic损失计算逻辑错误
    计算完平方和后,错误地将criticLoss赋值为rewards.size(),而非求平均损失,异常的损失值会导致反向传播时出现数值溢出或内存错误。


修复后的关键代码段

// library for sim functions
#include "include/simFunctions.cpp"

// create the sim class
Sim sim;

class Bot{
private:
  double currentScore;
  bool training = true;
  int currentTerm = 65;
  int previousTerm = 0;
public:
  const void* message = " ";
  int functionOutput;

  // activate or deactivate the hook
  void hook(bool activated) {
    if (activated == true) {
      Hook->setVelocity(2.0);
      sim.delay(130, "msec");
      Hook->setVelocity(0.0);
    } else if (activated == false) {
      Hook->setVelocity(-2.0);
      sim.delay(130, "msec");
      Hook->setVelocity(0.0);
    }
  }
  
    // training functions for network
  void trainingNetwork(NeuralNetwork& actor, NeuralNetwork& critic, int numEpisodes, double gamma, double learningRate, double GRADIENT_CLASH_THRESHOLD, double weight_decay) {
    
    AdamWOptimizer actorOptimizer(learningRate, 0.9, 0.999, 0.01, weight_decay);
    AdamWOptimizer criticOptimizer(learningRate, 0.9, 0.999, 0.01, weight_decay);
    
    actor.add_layer(Layer(3, 128, "relu", actorOptimizer));
    actor.add_layer(Layer(128, 128, "relu", actorOptimizer));
    actor.add_layer(Layer(128, 4, "linear", actorOptimizer));
    
    critic.add_layer(Layer(2, 128, "relu", criticOptimizer));
    critic.add_layer(Layer(128, 128, "relu", criticOptimizer));
    critic.add_layer(Layer(128, 1, "linear", criticOptimizer));
    
    for (int episode = 0; episode <= numEpisodes; ++episode) {
      vector<vector<double>> states;
      vector<double> actions, rewards, logProbs, values;
      
      if (left1->getVelocity() != 0.0) {
        sim.moveBot(0);
        sim.delay(50, "msec");
      }
      sim.resetSimManual();
      sim.programSetup();
      training = true;
      while (training == true) {
        double input1;
        double input2;
        double input3;
        
        // 修复input2的计算逻辑
        input1 = (left1->getVelocity() + left2->getVelocity() + left3->getVelocity()) / 3;
        input2 = (right1->getVelocity() + right2->getVelocity() + right3->getVelocity()) / 3;
        input3 = robot->getTime();
        // 直接初始化完整的state向量
        vector<double> state = {input1, input2, input3};
        states.push_back(state);
      
        vector<vector<double>> actionProbs = actor.forward({state});
        
        vector<vector<double>> valueEstimates = critic.forward({state});
        // 移除重复的push操作
        values.push_back(valueEstimates[0][0]);
        
        sim.delay(64, "msec");
      
        int action = (actionProbs[0][0] > actionProbs[0][1]) ? 0 : 1;
        logProbs.push_back(log(max(actionProbs[0][action], 1e-8)));
        
        functionOutput = action;
        
        cout << "MAINBOT: functionOutput = " << functionOutput << endl;
        functionConvert(functionOutput);
        
        sim.receive();
        if (receiv->getQueueLength() >= 1) {
          message = receiv->getData();
          currentScore = *(double *)message;
          rewards.push_back(currentScore);
          receiv->nextPacket();
        }
        
        if (robot->getTime() >= currentTerm) {
          training = false;
          previousTerm = currentTerm;
          currentTerm = currentTerm + 61;
        }
      }
      
      vector<double> advantages;
    for (int t = 0; t < rewards.size(); ++t) {
      double td_target = rewards[t] + (t < rewards.size() - 1 ? gamma * values[t + 1] : 0.0);
      advantages.push_back(td_target - values[t]);
    }
      
    double actorLoss = computeLoss(logProbs, advantages);
      
    // 修复criticLoss计算逻辑
    double criticLoss = 0.0;
    for (size_t i = 0; i < rewards.size(); ++i) {
      double td_target = rewards[i] + (i < rewards.size() - 1 ? gamma * values[i + 1] : 0.0);
      criticLoss += pow(td_target - values[i], 2);
    }
    // 计算平均损失
    criticLoss /= rewards.size();
      
    actor.backward({{actorLoss}}, GRADIENT_CLASH_THRESHOLD);
    actor.update_weights();
      
    critic.backward({{criticLoss}}, GRADIENT_CLASH_THRESHOLD);
    critic.update_weights();
    }
      
  }
  
  double computeLoss(const vector<double>& logProbs, const vector<double>& advantages) {
    double loss = 0.0;
    for (int i = 0; i < logProbs.size(); ++ i) {
      loss -= logProbs[i] * advantages[i];
    }
    return loss;
  }
  
  void functionConvert(int functionID) {
    if (functionID == 0) {
      sim.moveBot(0);
    } else if (functionID == 1) {
      sim.moveBot(1);
    } else if (functionID == -1) {
      sim.moveBot(2);
    } else if (functionID == 2) {
      sim.moveBot(3);
    } else if (functionID == -2) {
      sim.moveBot(4);
    }
  }
};

内容的提问来源于stack exchange,提问作者user27382745

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 16:24:51