PROS integer Problem

I was using the code from this post about a month ago.


I was using C++ and PROS but PROS didn’t like part of the code and I was not sure what to do about it.

#include "main.h"
#include "okapi/api.hpp"
#include "pros/api_legacy.h"

class PID {
private:
  double m_kP = 0;
  double m_kD = 0;
  int m_minDt = 10;

  okapi::Timer m_timer;
  double m_error = 0;
  double m_lastError = 0;
  double m_lastTime = 0;
  double m_derivative = 0;
  double m_output = 0;

public:
  PID(double kP, double kD, int minDt = 10);
  double calculateErr(double);
  double calculate(double, double);
  double getError();
  void reset();
  
};

PID::PID(double kP, double kD, int minDt) :
m_kP(kP), m_kD(kD), m_minDt(minDt) {
  m_lastTime = m_timer.millis().convert(okapi::millisecond);
}

double PID::calculateErr(double ierror) {
  m_error = ierror;
  
  //calculate delta time
  double dT = m_timer.millis().convert(okapi::millisecond) - m_lastTime;
  //abort if dt is too small
  if(dT < m_minDt) return m+output; //m+output is a problem
  
  //calculate derivative
  m_derivative = (m_error - m_lastError) / dT;
  
  //calculate output
  m_output = (m_error * m_kP) + (m_derivative * m_kD);
  //limit output
  if(std::abs(m_output) > 127) output = sgn(m_output) * 127; //output and sgn is a problem

  //save values
  m_lastTime = m_timer.millis().convert(okapi::millisecond);
  m_lastError = m_error;
  
  return m_output;
}

double PID::calculate(double target, double current) {
  return calculateErr(target - current);
}

double PID::getError() {
  return m_error;
}

void PID::reset() {
  m_error = 0;
  m_lastError = 0;
  m_lastTime = m_timer.millis().convert(okapi::millisecond);
  m_derivative = 0;
  m_output = 0;
}

void autonomous() 
{
  PID myPid (1,0.1);
  while(true)
  {
    double motorPower = myPid.calculate(100, 127);
  }
}

So I figured the forum would be helpful. Any explanations would be great. I noted what was a problem with PROS with a comment in the code. Thanks!

These don’t appear to be PROS problems. They appear to be C++ knowledge problems.

First problem, you have never declared the variables m and output before trying to read from them. The compiler should be telling you this with an error message or two. Second problem, same as the first: you have never declared output before trying to assign a value to it.

If I were to hazard a guess, it appears to be two typos as you tried to type m_output and goofed, putting a + in the first and omitting the m_ in the second. Computers on this level will do exactly what you tell them and infer nothing about what you meant. Be sure to dot all your i’s and cross all your t’s.

edit: for sgn, you haven’t included any prototype or header that defines what that function does

That code was just a proof-of-concept I made, showing a way to structure things.
You have to do a little bit to get it to compile.

First of all, yes, when writing that I did a little typo.
Notice how the “+” key is right next to the “_” key? =)
Replace m+output with m_output.
And John is right, I also forgot to put the m_ in the other line.

Second, you need to know more about C++. If you are motivated, read learncpp.com as much you can.
You need to understand how classes work, and how to set up a project to have class header files and source files. All the code I provided was not meant to be pasted into one file.
You need a header file which contains the forward declarations, and a source (cpp) file that contains the actual code. If you continued with the way you are doing, you will run into linker issues very fast.
You also need to know proper syntax so you can solve issues like the + on your own, and understand what the problem is with the sections you showed.

You will also need to supply your own sgn function. The one I use is

template <typename T> int sgn(T val) {
    return (T(0) < val) - (val < T(0));
}

Again, you need to know where to put things in header files.

Finally, the void autonomous() was just an example use case. Its just showing how you would use it. It is not meant to be put anywhere.
And it does nothing, does not use any sensors or motors, and has no delay.

Learn how to write C++, and you will learn how you can implement this.

Try to learn from this structure and modular methodology. Its just a PID loop, you should learn how to make one yourself. It is not meant to be copy/pasted, it is meant to demonstrate a good way of creating a generic PID utility.

2 Likes