Memory Permission Error 03803930

Hi, I’m getting a memory permission error 03803930.
What is the cause of this?

I was unable to find this specific error code from past discussions.

I made sure that all of my vars are not highlighted in yellow and I deleted the build folder.

Do you have any three wire sensors?

Yes, I have two optical shaft encoders.

Previously, when I still had the two encoders declared in the code, the code was working.

Can you share your code. All of your code?

You might have declared them using the setup thing in the top right corner and declared it again in main.image

You need to declare it in robot-config only using this : image

I narrowed down the issue:
It is when I try to make a global object of a class that I declared in another file. I included this file in main though.

Does that help?

This is a well known issue.

2 Likes

I don’t understand the post you linked. Can you explain it to me?

Here is the line in main.cpp that causes the issue:
Position currentPosition(0, 0);

Position is a class that is defined in a header file which I included in main.cpp

What I was saying in that post, is that the most common cause of the memory permission error is the use of the Brain or Brain.ThreeWirePort instance before it has been created. So something like

gyro myGyro = vex::gyro(Brain.ThreeWirePort.A);

used in main.cpp will generally cause the error.

Does you position class use Brain.ThreeWirePort in defining optical shaft encoders ?

3 Likes

It uses two encoder objects, but I defined those in robot-config.cpp. E

Every device is defined in robot-config.cpp only

Can you post the code for the Position class ?

2 Likes
#include <cmath>
#include <stdio.h>
#define SMALL_LIMIT 0.0000001
#define CLICKS_PER_INCH 41.6696578277
//mutex mtx;

class Position
{
private:
  double xCoord = 0;
  double yCoord = 0;
  double robotHeading = 0; //value in degrees

  double xClicks = 0;
  double yClicks = 0;

public:

  Position()
  {
    xCoord = 0;
    yCoord = 0;
    robotHeading = fmod(-inertialSensor.heading() + 450, 359);
    xClicks = xEncoder.rotation(rotationUnits::raw);
    yClicks = yEncoder.rotation(rotationUnits::raw);
    
  }

  Position(double x, double y)
  {
    xCoord = x;
    yCoord = y;
    robotHeading = fmod(-inertialSensor.heading() + 450, 359);
    xClicks = xEncoder.rotation(rotationUnits::raw);
    yClicks = yEncoder.rotation(rotationUnits::raw);
  }

  Position(const Position &other)
  {
    this -> xCoord = other.xCoord;
    this -> yCoord = other.yCoord;
    this -> robotHeading = other.robotHeading;
    this -> xClicks = other.xClicks;
    this -> yClicks = other.yClicks;
  }

  double getXCoord()
  { return xCoord; }

  double getYCoord()
  { return yCoord; }

  double getHeading()
  { return robotHeading; }

  double getYClicks()
  { return yClicks; }

  double getXClicks()
  { return xClicks; }

  void setXCoord(double n)
  { xCoord = n; }

  void setYCoord(double n)
  { yCoord = n; }

  void setXClicks(double n)
  { xClicks = n; }

  void setYClicks(double n)
  { yClicks = n; };

  void setPositionHeading(double n)
  { robotHeading = n; }

  void updateSensorValues()
  {
    xClicks = xEncoder.rotation(rotationUnits::raw);
    yClicks = yEncoder.rotation(rotationUnits::raw);
    robotHeading = fmod(-inertialSensor.heading()+ 450, 359);
  }

  void updatePosition(Position &previousPosition)
  {
    //mtx.lock();
    updateSensorValues();

    double xDistance = (xClicks - previousPosition.getXClicks()) / CLICKS_PER_INCH;
    double yDistance = (yClicks - previousPosition.getYClicks()) / CLICKS_PER_INCH;
    double angleDifference = previousPosition.getHeading() - robotHeading; //in degrees
    double radRobotHeading = robotHeading * (M_PI / 180);
    double F = 0.00005;
    xDistance -= (F * angleDifference);

    xCoord += yDistance * cos(radRobotHeading) - xDistance * sin(radRobotHeading);
    yCoord += yDistance * sin(radRobotHeading) + xDistance * cos(radRobotHeading);
    
    previousPosition.setXClicks(xClicks);
    previousPosition.setYClicks(yClicks);
    previousPosition.setPositionHeading(robotHeading);
    previousPosition.setXCoord(xCoord);
    previousPosition.setYCoord(yCoord);
   // mtx.unlock();
  }
    

  void printPosition()
  {
    printf("Position (%lf, %lf, %lf)\n", xCoord, yCoord, robotHeading);
  }
};

The default constructor works but the constructor with two parameters does not. (By using the constructor with no parameters, I do not get the error)

so all your constructors are using instances of sensors that probably have not been created.
There’s no guarantee for the order in which the global constructors across files are called (generally it’s alphabetical order) so constructors for global objects in main.cpp can be called before robot_config.cpp. You use inertialSensor, xEncoder and yEncoder before they have been initialized, that’s probably the cause of the error.

Not sure why that would be, I’ll setup a test later.

move this to the end of robot_config.cpp then declare in a header so you can access globally.

Position currentPosition(0, 0);
4 Likes

yea, both constructors throw the same error for me.

Position currentPosition;

and

Position currentPosition(0,0);
4 Likes

When I used the default constructor I wrote Position currentPosition()

Do you think it would be better if I passed the inertial sensor and two encoders as parameters in the constructor?

That didn’t create an instance, you declared a function returning instance of Position class.

probably will have the same issue unless they are created in the same file (and before) you create the instance of the Position class. The root cause here is again the use of Brain.ThreeWirePort before it exists.

you could just skip those sensors in robot_config.cpp and create them inside the Position class.

class Position
{
private:
  double xCoord = 0;
  double yCoord = 0;
  double robotHeading = 0; //value in degrees

  double xClicks = 0;
  double yClicks = 0;

  vex::triport     ThreeWirePort = vex::triport ( vex::PORT22 );
  vex::inertial    inertialSensor = vex::inertial( vex::PORT1 );
  vex::encoder     xEncoder = vex::encoder( ThreeWirePort.A );
  vex::encoder     yEncoder = vex::encoder( ThreeWirePort.C );

public:

3 Likes

I understand now.

Thank you for the help.