【问题标题】:Function call different behavior in main and library函数在主库和库中调用不同的行为
【发布时间】:2014-04-10 10:36:36
【问题描述】:

我遇到了一件很奇怪的事情,前两天我尝试调试代码。 我在 Windows 7 64 位操作系统上运行代码。我主要通过知道输入信号来计算数学模型,该模型将应用于控制算法SOOP。主要计算是可以的,但在soop 函数中,在做同样的事情时,我得到了接近但不相同的结果。为什么? 我也厌倦了float,得到了同样的结果。

如果我在非主函数中计算,double 是否会四舍五入

主要:

#include <unistd.h>
#include <iostream>
#include <windows.h>
#include <fstream>
#include <math.h>
#include "model.h"
#include "SOOP.h"

using namespace std;

int main( void )
{
    ofstream myfile;
    myfile.open ("modelTest.txt");
    stateE current_state; // = new stateE;
    initstateE(current_state);
    current_state.variables[0] = 0.0;

    current_state.variables[0] = -3.0*PI/2.0;
    cout <<  "program init" << endl;
   // ==============Model testing
    myfile << current_state.variables[0] <<", "<< current_state.variables[2] <<", "<<current_state.reward << ", "<< fmod((current_state.variables[0])+ PI, 2.0 * PI) -PI <<endl;
    double utmp = -10.0;
    for (int i=0;i<3;i++)
    {
        current_state.variables[0] = -3.0*PI/2.0;
        copyStateE(current_state, nextstateE(current_state, utmp));
        utmp = utmp+10.0;
        myfile << current_state.variables[0] <<", "<< current_state.variables[2] <<", "<<current_state.reward << ", "<< fmod((current_state.variables[0])+ PI, 2.0 * PI) -PI <<endl;
    }
     // ==============SOOP testing
     initstateE(current_state);
    current_state.variables[0] = -3.0*PI/2.0;

    double commnadSignal[initlen];
    for(int i=0; i<1; i++)
    {    
        memcpy(commnadSignal,soop(current_state),sizeof(double)*initlen);
        copyStateE(current_state,nextstateE(current_state, commnadSignal[0]));
    }

    myfile.close();
    return 0;
}

模型库:

stateE nextstateE(stateE s, double votlageSignal) {
    std::cout<< "in nextstateE"<< std::endl;
    stateE newstateE;// = (stateE*)malloc(sizeof(stateE));
    memcpy(newstateE.variables, s.variables, sizeof(double) * nbHiddenstateEVariables);
    newstateE.isTerminal = s.isTerminal;
    std::cout << " v "<< votlageSignal << " l "<< s.variables[0] << std::endl;
    double Vm = votlageSignal;

    double lambda = s.variables[0];
    double dLambda = s.variables[1];
    double theta = s.variables[2];
    double dTheta = s.variables[3];

    double thetaNext = theta + timeStep*dTheta;
    double dThetaNext = dTheta + timeStep*( (1/(aP*cP-pow(bP,2)*pow(cos(lambda),2))) *(-bP*cP*sin(lambda)*pow(dLambda,2)+bP*dP*sin(lambda)*cos(lambda)-cP*eP*dTheta+cP*fP*Vm) );
    double lambdaNext = lambda + timeStep*dLambda;
    double dLambdaNext = dLambda + timeStep*( (1/(aP*cP-pow(bP,2)*pow(cos(lambda),2))) *(aP*dP*sin(lambda)-pow(bP,2)*sin(lambda)*cos(lambda)*pow(dLambda,2)-bP*eP*cos(lambda)*dTheta+bP*fP*cos(lambda)*Vm) );

    //========== Normalization of lambda and theta
    if (lambdaNext>0)
            lambdaNext = fmod(lambdaNext+PI, 2.0*PI)-PI;
    else
            lambdaNext = fmod(lambdaNext-PI, 2.0*PI)+PI;
    if (thetaNext>0)
            thetaNext = fmod(thetaNext+PI, 2.0*PI)-PI;
    else
            thetaNext = fmod(thetaNext-PI, 2.0*PI)+PI;

    newstateE.variables[0] = lambdaNext;
    newstateE.variables[1] = dLambdaNext;
    newstateE.variables[2] = thetaNext;
    newstateE.variables[3] = dThetaNext;

    double newReward;
    if(s.isTerminal) {
        newReward = 0.0;
    } else {    
        newReward = 1 - (pow(lambdaNext,2.0)*qReward + pow(votlageSignal,2.0)*rReward)/(pow(PI,2.0)*qReward+ pow(maxVoltage,2.0)*rReward);
    }
    newstateE.reward=newReward;
    return newstateE;



}

void copyStateE(stateE& destination, stateE original)
{ 
    initstateE(destination);
    destination.variables[0] = original.variables[0];   // lambda
    destination.variables[1] = original.variables[1];   // dLambda
    destination.variables[2] = original.variables[2];   // theta
    destination.variables[3] = original.variables[3];   // dTheta
    destination.isTerminal = 0;
    destination.reward = original.reward;

}

控制器库使用模型库:

double * soop(stateE& s0)
{
    ofstream myfile;
    myfile.open ("soopTest.txt");

    bool stopFlag = false;

    unsigned int counter = 0;
    unsigned int currentBudget = 0;
    unsigned int listLenght = 0;
    unsigned int maxLengthSequence = 0;
    double tmpU = -10.0;
    for (int i=0;i<3;i++)
    {
        double sPtmp[initlen] = {0};
        unsigned int stmp[initlen] = {0};
        stateE newstateE[initlen];

        stateE tmpE;

        sPtmp[0] = ((double)i)/3.0;
        stmp[0] = 1;
        initstateE(tmpE);
        tmpE.variables[0]=-3.0*PI/2.0;

        copyStateE(tmpE, nextstateE(tmpE , tmpU ));
        tmpU = tmpU + 10.0;

            newstateE[0] = nextstateE(s0, unnormU(middleOfBox((double)i/3.0, stmp[0])) );


            myfile << "U norm "<< middleOfBox((double)i/3.0, stmp[0])<< " Unorm "<<unnormU(middleOfBox((double)i/3.0, stmp[0])) << endl;
            myfile <<"alp " << tmpE.variables[0] << " th " << tmpE.variables[2] <<  " R " << tmpE.reward << endl;
            myfile <<"alp " << newstateE[0].variables[0] << " th " << newstateE[0].variables[2] <<  " R " << newstateE[0] .reward << endl;
            myfile << endl;

    }
    myfile.close();
}

modelTest.txtsoop Test.txt 两个文本文件应该显示相同的结果,因为我在 main 和 soop 函数中应用了相同的输入参数(s0 和 [-10,0,10])。但是我在文本文件中得到了不同的结果。 soop Test文件:

U norm 0.166667 Unorm -10
alp 1.5708 th 0 R 0.75
alp 1.5708 th 0 R 0.75

U norm 0.5 Unorm 0
alp 1.5708 th 0 R 0.75
alp 1.5708 th 0 R 0.75

U norm 0.833333 Unorm 10
alp 1.5708 th 0 R 0.75
alp 1.5708 th 0 R 0.75

modelTest文件:

alp 1.5708, th 0, R 0.75 (for s0 and -10)
alp 1.57084, th -0.000115852, R 0.749986 (for s0 and 0)
alp 1.57088, th -0.000230942, R 0.749972 (for s0 and 10)

【问题讨论】:

  • 您的 mainsoop 函数看起来不同。在soop 中,初始化位于for 循环内。
  • true,在main 中,我知道 unnormalized U,即 = -10、0 和 10。在 soop 中,i 的函数中计算相同的值。该算法应该是灵活的...如果将来需要,我可以计算 4 个初始 unnormalized Us
  • 好的,现在我在mainsoop 有同样的东西,同样的 wong 结果。 tmpE 应该等于 newtstateE

标签: c++ function debugging struct discretization


【解决方案1】:

我的错,在main我没有初始化current_state的所有状态(只有一个角度)。 initStateE(current_state)main 循环中丢失。

下一个错误,voltageSignal 的奖励因子,'rReward = 0' 所以奖励不会改变控制值的函数。

最大的错误是假设系统角状态参数在第一次模拟后会发生变化。我对 f(Q(t),U(t)) 使用欧拉离散化 - 二阶微分方程,因此控制信号仅对第一次迭代中的一阶导数和位置在第 2 次迭代后生效。

P_{k+1} = P_k + daltaT * Q_k 
Q_{k+1} = Q_k + deltaT * f(Q_k, U_k)

其中 deltaT 是采样时间。

【讨论】:

    猜你喜欢
    • 2015-02-04
    • 1970-01-01
    • 2014-09-08
    • 2011-03-13
    • 2013-12-10
    • 2013-01-03
    • 2020-01-09
    • 1970-01-01
    • 2013-11-28
    相关资源
    最近更新 更多