1

我有一个名为 PID 的类。我#include 类的标题。我一直在各种文件中使用这个类,包括错误指向的文件。编译器抱怨定义函数声明本身void dispPid(char *name, PID &pid){}。函数的所有内容都被注释掉了。该错误读取AutoTrucker:-1: error: 'PID' has not been declared没有其他错误。完整地注释掉函数可以完全消除错误,编译并正常工作。

真正让我困惑的是:

  1. 错误指向第-1行
  2. 该文件存在,并且包含在
  3. 我使用上面的这个 PID 类作为指针:
PID *pid;
if (chk(arg2,"roll")){pid = &aircraft.ap.pid.wingLeveler;}
else if (chk(arg2,"heading") || chk(arg2,"hdg")){pid = &aircraft.ap.pid.headingHold;}
else if (chk(arg2,"pitch")){pid = &aircraft.ap.pid.pitchHold;}
...

上面直接指定的这段代码可以编译并正常工作。那么给了什么?

编辑 2: 这真是一个吉米钻机,它让我感到恶心。不过是暂时解决了问题。那么给了什么?编译器不喜欢 PID 类作为函数参数,但它发现它在函数内部是可以接受的?我真的很想找到一个合适的解决方案,而不是传入一个 void 指针并转换它!

void dispPid(const char *name, void *tpid)
{
  PID &pid = *((PID*)tpid);
  ...
}

编辑:(根据要求添加更多源代码)

void cmdsPid(char *buffer)
{
  if (chk(buffer,"pid"))
  {
    char *arg1 = next(buffer);
    if (chk(arg1,"ls"))
    {
      char *arg2 = next(arg1);
      if (chk(arg2,"") || chk(arg2,"all"))
      {
        /*
        Serial.println("Listing all PIDs:");
        dispPid("Roll",aircraft.ap.pid.wingLeveler);
        Serial.print("\t");
        dispPid("Heading",aircraft.ap.pid,headingHold);
        dispPid("Pitch",aircraft.ap.pid,pitchHold);
        Serial.print("\t");
        dispPid("V-Rate",aircraft.ap.pid.climbHold);
        Serial.print("\t\t");
        dispPid("Altitude",aircraft.ap.pid.altHold);
        dispPid("Throttle",aircraft.ap.pid.throttleHold);
        dispPid("Slip",aircraft.ap.pid.slipHold);
        */
      }
      else
      {
        Serial.print("Unknown argument");
      }
    }
    else if (chk(arg1,"w"))
    {
      char *arg2 = next(arg1);//name
      char *arg3 = next(arg2);//attr
      char *arg4 = next(arg3);//val
      double val = 0.0;
      bool onoff = false;
      if (chk(arg3,"inv"))
      {
        onoff = (chk(arg4,"off") || chk(arg4,"-"));
      }
      else if (chk(arg3,"max") || chk(arg3,"min"))
      {
        if (chk(arg4,"off") || chk(arg4,"-"))
        {
          onoff = false;
        }
        else
        {
          onoff = true;
          val = parseDoubleArg(arg4);
        }
      }
      else
      {
        val = parseDoubleArg(arg4);
      }
      PID *pid;
      if (chk(arg2,"roll")){pid = &aircraft.ap.pid.wingLeveler;}
      else if (chk(arg2,"heading") || chk(arg2,"hdg")){pid = &aircraft.ap.pid.headingHold;}
      else if (chk(arg2,"pitch")){pid = &aircraft.ap.pid.pitchHold;}
      else if (chk(arg2,"vrate")){pid = &aircraft.ap.pid.climbHold;}
      else if (chk(arg2,"alt")){pid = &aircraft.ap.pid.altHold;}
      else if (chk(arg2,"th")||chk(arg2,"thr")||chk(arg2,"thro")||chk(arg2,"throttle")){pid = &aircraft.ap.pid.throttleHold;}
      else if (chk(arg2,"slip")){pid = &aircraft.ap.pid.slipHold;}
      if (chk(arg3,"p")){pid->setPGain(val);}
      else if (chk(arg3,"i")){pid->setIGain(val);}
      else if (chk(arg4,"d")){pid->setDGain(val);}
      else if (chk(arg4,"max"))
      {
        if (onoff){pid->setLimitMax(val);}
        else{pid->disableMaxLimit();}
      }
      else if (chk(arg4,"min"))
      {
        if (onoff){pid->setLimitMin(val);}
        else{pid->disableMinLimit();}
      }
    }
    else
    {
      Serial.println("Unknown argument");
    }
  }
}

void dispPid(char *name, PID &pid){}

PID 类(标头):

#pragma once

#define PID_VERSION "1.1"

#include <inttypes.h>

#define allowLimitMax 1
#define allowLimitMin 2
#define invert 4
#define enabled 8

class PID
{
private:
    double pGain,iGain,dGain;
    double integrator;
    double *input,*output,*setpoint;
    double lastInput;
    double limitMax,limitMin;

    char settings;

public:
    struct Spid {
        double p,i,d,limitMax,limitMin;
        char settings;
    };

    PID();//constructor

    //getters
    double getPGain();
    double getIGain();
    double getDGain();
    double getLimitMax();
    double getLimitMin();
    bool isLimitMaxSet();
    bool isLimitMinSet();
    bool isInverted();

    //setters
    void setPGain(double newPGain);
    void setIGain(double newIGain);
    void setDGain(double newDGain);
    void setPIDGain(double newPGain, double newIGain, double newDGain);
    void setInput(double *newInput);
    void setOutput(double *newOutput);
    void setSetpoint(double *newSetpoint);
    void setIOS(double *newInput, double *newOutput, double *newSetpoint);
    void setLimitMax(double newLimitMax);
    void setLimitMin(double newLimitMin);
    void setLimits(double newLimitMin, double newLimitMax);
    void disableMaxLimit();
    void disableMinLimit();
    void disableLimits();
    void zeroOutIntegrator();
    void nullOut();
    void setInverted(bool newInvert);

    //actions
    void run();
    void run(double dt);

    void setFrom(Spid copy);
    void copy(Spid &copy);
};
4

0 回答 0