Steven10172
Steven10172

Reputation: 2013

Function Pointer to function of a pointer

I'm currently working with a custom pneumatic robot arm and was attempting to design a queue for different tasks. In the process of designing the queue I came up with the logic of having the queue store function pointers and an int to pass to the function and the queue would keep attempting to run the function in the queue until it returned true.

While doing basic functions the queue works, but when trying to implement it in the following way it fails:

  functionQueue.push(_lowerArm->waitForHoldingPosition, 100); // Lower Arm 100%

Error Message:

Arm.h:180: error: no matching function for call to 'Queue<bool (*)(int), 50>::push(<unresolved overloaded function type>, int)'
/Queue.h:201: note: candidates are: bool Queue<T, queueMaxSize>::push(T, int) [with T = bool (*)(int), int queueMaxSize = 50]

In an attempt to fix the issue I tried taking a reference of the _lowerArm->waitForHoldingPosition, but it didn't prove successful. If someone could point me into the right direction I would greatly appreciate it.

Rest of the Code:

AirCylinder lowerArm(4, 13, 7, 1, false); //Green, White
AirCylinder upperArm(10, 11, 6, 2, true); //Yellow, Orange
AirCylinder wrist(8, 9, 5, 3, true); //Red, Blue
Arm arm(&lowerArm, &upperArm, &wrist, SERVO_PIN);

loop() { /* Do Core Stuff Here */

Arm.h

#include <Arduino.h>
#include "Queue.h"

#ifndef ARM_H
#define ARM_H

#define QUEUE_SIZE 50

class Arm {
  private:
    AirCylinder* _lowerArm;
    AirCylinder* _upperArm;
    AirCylinder* _wrist;
    byte _servoPin;
    byte _servoPosition;
    byte _currentRoutine;
    boolean _doingRoutine;
    Queue<bool(*)(int),QUEUE_SIZE> functionQueue;

    void _setFingers(byte);
    void _doRoutine();
    void _pickUpCone();
    void _scoreConeLow();
    void _scoreConeHigh();
    void _scoreConeeSideways();
    void _storeCone();
    void _rest();
    void _stabilize();


  public:
    Arm(AirCylinder *lowerArm, AirCylinder *upperArm, AirCylinder *wrist, byte servoPin);
    void stabilize();
    void openFingers()             {  _setFingers(Arm::SERVO_OPEN);   }
    void closeFingers()            {  _setFingers(Arm::SERVO_CLOSE);  }
    void setFingers(byte servoPos) {  _setFingers(servoPos);    }
    void doRoutine();
    void doRoutine(byte);
    void calibrateRoutine(byte);

    static const byte SERVO_OPEN = 0;
    static const byte SERVO_CLOSE = 180;

    static const byte PICKUP_CONE = 0;
    static const byte SCORE_CONE_LOW = 1;
    static const byte SCORE_CONE_HIGH = 2;
    static const byte SCORE_CONE_SIDEWAYS = 3;
    static const byte STORE_CONE = 4;
    static const byte RESTING = 5;

};

Arm::Arm(AirCylinder *lowerArm, AirCylinder *upperArm, AirCylinder *wrist, byte servoPin) {
  // Set a reference to all the arm cylinders
  _lowerArm = lowerArm;
  _upperArm = upperArm;
  _wrist = wrist;

  // Set the pin the servos are on
  _servoPin = servoPin;

  _doingRoutine = false;
}

void Arm::_scoreConeLow() {
  // Grab cone from bot
  // Lower Arm - 100%
  // Upper Arm - 50%
  // Wrist - 20%
  // Lower Arm - 80%

  // Put cone down
  // Lower Arm - 100%
  // Upper Arm - 75%
  // Wrist - 0%
  // Lower Arm - 70%
  // Upper Arm - 60%
  // Lower Arm - 40%

  functionQueue.push(_upperArm->waitForHoldingPosition, 30); // Upper Arm 50%
  functionQueue.push(_wrist->waitForHoldingPosition, 20); // Wrist 20%
  functionQueue.push(_lowerArm->waitForHoldingPosition, 80); // Lower Arm 80%

  functionQueue.push(_lowerArm->waitForHoldingPosition, 100); // Lower Arm 100%
  functionQueue.push(_upperArm->waitForHoldingPosition, 75); // Upper Arm 75%
  functionQueue.push(_wrist->waitForHoldingPosition, 0); // Wrist 0%
  functionQueue.push(_lowerArm->waitForHoldingPosition, 70); // Lower Arm 70%
  functionQueue.push(_upperArm->waitForHoldingPosition, 60); // Upper Arm 60%
  functionQueue.push(_lowerArm->waitForHoldingPosition, 40); // Lower Arm 40%
}

AirCylinder.h

class AirCylinder {
  private:
   // Bunch of methods not used in this example

  public:
    /* Constructors */
    AirCylinder();
    AirCylinder(byte retractPin, byte extendPin, byte extendPressureHolderPin, byte potPin);
    AirCylinder(byte retractPin, byte extendPin, byte extendPressureHolderPin, byte potPin, boolean isInverse);

    /* Setters */

    /* Getters */

    /* Functions */
    bool waitForHoldingPosition(int position);
};

/**
  * waitForHoldingPosition
  *
  * Attempts to stablize the Air Cylider at the current Holding Position
  * function returns true when the position is met
  *
  */
bool AirCylinder::waitForHoldingPosition(int position) {
  setHoldingPosition(position);
  if(abs(getCurrentPosition() - position) > THRESHOLD_PERCENT) {
    // Cylinder is not within the threshold
    return false;
  }
  return true; // Cylinder is within the threshold
}

Upvotes: 1

Views: 92

Answers (1)

Arjun Sreedharan
Arjun Sreedharan

Reputation: 11453

Your waitForHoldingPosition is of type bool (AirCylinder::*)(int).

But your Queue template expects bool (*)(int). They are not the same.

Your Queue should be:

Queue<bool(AirCylinder::*)(int), QUEUE_SIZE> functionQueue;

Upvotes: 1

Related Questions