1

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
}

1 Answer 1

1

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;
Sign up to request clarification or add additional context in comments.

3 Comments

Is there a way to type cast the insert into the queue where it can be a generic function pointer? As I'd like the queue to also handle private functions of the arm class.
@Steven10172 Would making waitForHoldingPosition static serve you?
not really. It needs to do something specific for each air cylinder. I'd really like to be able to type cast to a generic function pointer as I need be able to add bool Arm::moveServo() and bool Arm::hasCone() to the queue.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.