Frage

I met a very strange thing, two days ago I try to debug the code. I'm running the code on a Windows 7 64bit OS. In the main I calculate a mathematical model by knowing the input signal, which will be applied in the control algorithm SOOP. The calculation is ok in the main, but in the soop function while doing the same thing i have close but not identical results. Why? I tired with float too and I got the same result.

Does double get rounded if I calculate in a function not in the main?

Main:

#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;
}

The model library:

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;

}

The controller library uses the model library:

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();
}

The two text files modelTest.txt and soop Test.txt should show the same results, cuz I applay the same input parameters (s0 and [-10,0,10]) in the main and in the soop function. But I get different rusults in the text files. soop Test file:

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 file:

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)
War es hilfreich?

Lösung

My mistake, in the main I didn't initialized all the states of current_state (only one angle). initStateE(current_state) is missing in the main loop.

Next mistake, that the reward factor for voltageSignal, 'rReward = 0' so the Reward wont change in function of the control value.

The biggest mistake is to suppose that the systems angular state parameter would change after the first simulation. I'm using Euler discrezitation for f(Q(t),U(t)) - a 2nd order differential equation, so a control signal has effect only on first derivative in the first iteration and on the position it has effect after the 2nd iteration.

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

where deltaT is the sampling time.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top