Okapi Errors

Does anyone know why I keep getting this error with Okapi in PROS and how I fix it? I am using pros 3.1.4, it was re-installed fresh just a couple days ago with okapi. I have no "using namespace"s, so there is no contradictory okapi and pros namespace, and the “okapi/api.hpp” is included in my “main.h”. Yet, I keep getting an error stating

>     /include/globals.hpp:13:8: error: 'okapi' does not name a type
>      extern okapi::ControllerButton intakeForward;
>             ^~~~~
>     ./include/globals.hpp:14:8: error: 'okapi' does not name a type
>      extern okapi::ControllerButton intakeReverse;
> src/opfunctions.cpp:66:75: error: no matching function for call to 'okapi::ControllerButton::ControllerButton(pros::controller_digital_e_t, bool)'
>  okapi::ControllerButton intakeForward(pros::E_CONTROLLER_DIGITAL_R1, false);
>                                                                            ^
> In file included from ./include/okapi/api.hpp:46:0,
>                  from ./include/main.h:48,
>                  from src/opfunctions.cpp:2:
> ./include/okapi/impl/device/button/controllerButton.hpp:19:3: note: candidate: okapi::ControllerButton::ControllerButton(okapi::ControllerId, okapi::ControllerDigital, bool)
>    ControllerButton(ControllerId icontroller, ControllerDigital ibtn, bool iinverted = false);
>    ^~~~~~~~~~~~~~~~
> ./include/okapi/impl/device/button/controllerButton.hpp:19:3: note:   no known conversion for argument 1 from 'pros::controller_digital_e_t' to 'okapi::ControllerId'
> ./include/okapi/impl/device/button/controllerButton.hpp:17:3: note: candidate: okapi::ControllerButton::ControllerButton(okapi::ControllerDigital, bool)
>    ControllerButton(ControllerDigital ibtn, bool iinverted = false);
>    ^~~~~~~~~~~~~~~~
> ./include/okapi/impl/device/button/controllerButton.hpp:17:3: note:   no known conversion for argument 1 from 'pros::controller_digital_e_t' to 'okapi::ControllerDigital'
> ./include/okapi/impl/device/button/controllerButton.hpp:15:7: note: candidate: constexpr okapi::ControllerButton::ControllerButton(const okapi::ControllerButton&)
>  class ControllerButton : public ButtonBase {
>        ^~~~~~~~~~~~~~~~
> ./include/okapi/impl/device/button/controllerButton.hpp:15:7: note:   candidate expects 1 argument, 2 provided
> ./include/okapi/impl/device/button/controllerButton.hpp:15:7: note: candidate: constexpr okapi::ControllerButton::ControllerButton(okapi::ControllerButton&&)
> ./include/okapi/impl/device/button/controllerButton.hpp:15:7: note:   candidate expects 1 argument, 2 provided
> src/opfunctions.cpp:67:75: error: no matching function for call to 'okapi::ControllerButton::ControllerButton(pros::controller_digital_e_t, bool)'
>  okapi::ControllerButton intakeReverse(pros::E_CONTROLLER_DIGITAL_L1, false);
>                                                                            ^
> In file included from ./include/okapi/api.hpp:46:0,
>                  from ./include/main.h:48,
>                  from src/opfunctions.cpp:2:
> ./include/okapi/impl/device/button/controllerButton.hpp:19:3: note: candidate: okapi::ControllerButton::ControllerButton(okapi::ControllerId, okapi::ControllerDigital, bool)
>    ControllerButton(ControllerId icontroller, ControllerDigital ibtn, bool iinverted = false);
>    ^~~~~~~~~~~~~~~~
> ./include/okapi/impl/device/button/controllerButton.hpp:19:3: note:   no known conversion for argument 1 from 'pros::controller_digital_e_t' to 'okapi::ControllerId'
> ./include/okapi/impl/device/button/controllerButton.hpp:17:3: note: candidate: okapi::ControllerButton::ControllerButton(okapi::ControllerDigital, bool)
>    ControllerButton(ControllerDigital ibtn, bool iinverted = false);
>    ^~~~~~~~~~~~~~~~
> ./include/okapi/impl/device/button/controllerButton.hpp:17:3: note:   no known conversion for argument 1 from 'pros::controller_digital_e_t' to 'okapi::ControllerDigital'
> ./include/okapi/impl/device/button/controllerButton.hpp:15:7: note: candidate: constexpr okapi::ControllerButton::ControllerButton(const okapi::ControllerButton&)
>  class ControllerButton : public ButtonBase {
>        ^~~~~~~~~~~~~~~~
> ./include/okapi/impl/device/button/controllerButton.hpp:15:7: note:   candidate expects 1 argument, 2 provided
> ./include/okapi/impl/device/button/controllerButton.hpp:15:7: note: candidate: constexpr okapi::ControllerButton::ControllerButton(okapi::ControllerButton&&)
> ./include/okapi/impl/device/button/controllerButton.hpp:15:7: note:   candidate expects 1 argument, 2 provided

and here is what im trying to do

In hpp file

extern okapi::ControllerButton intakeForward;
extern okapi::ControllerButton intakeReverse;

In cpp file

> okapi::ControllerButton intakeForward(pros::E_CONTROLLER_DIGITAL_R1, false);
> okapi::ControllerButton intakeReverse(pros::E_CONTROLLER_DIGITAL_L1, false);
> enum Direction {forward, reverse, stopped};
> enum Direction intakeDirection = stopped;
> 
> void intakeOP() {
>   if(intakeForward.changedToPressed()){
>     if(intakeDirection != forward) {
>       intake_right.move_velocity(200);
>       intake_left.move_velocity(200);
>       intakeDirection = forward;
>     }
>     else {
>       intake_right.move_velocity(0);
>       intake_left.move_velocity(0);
>       intakeDirection = stopped;
>     }
>   }
>   if(intakeReverse.changedToPressed()){
>     if(intakeDirection != reverse) {
>       intake_right.move_velocity(-200);
>       intake_left.move_velocity(-200);
>       intakeDirection = reverse;
>     }
>     else {
>       intake_right.move_velocity(0);
>       intake_left.move_velocity(0);
>       intakeDirection = stopped;
>     }
>   }
> }

is not okapi

i think you need something like okapi::ControllerDigital::R1

You might have a few problems here.

Firstly, do as @rpm said and pass the proper enum to the ControllerButton.
With a couple exceptions that are fixed in okapi v4, okapi will almost never expect you to pass it something that belongs in the pros:: namespace.
If you read the error that said
note: no known conversion for argument 1 from 'pros::controller_digital_e_t' to 'okapi::ControllerDigital' you might have had a clue as to what was going wrong.

As for the 'okapi' does not name a type error, you might have some weird header recursion or something.
Make sure

  • none of your header files are included into main.h or api.h, as they could potentially be included into okapi before okapi was included into them.
  • you actually include main.h into your header files such as globals.hpp, so that they can see okapi.

Let me know how it goes!

1 Like

@theol0403 @rpm

Thank you guys so much,

Switching to okapi::ControllerDigital::R1 easily fixed the problem. I was attempting to follow this lift movement tutorial on the PROS website and it appeared as if they had used E_CONTROLLER_DIGITIAL_R1. I’m not quite sure why its done like that in the tutorial now tho…

https://pros.cs.purdue.edu/v5/okapi/tutorials/walkthrough/lift-movement.html

About the header files:
I rearranged my the order of inclusion for my header files and the problem was fixed. I was under the impression that the include preprocessor was not affected by this (I should probably go read more about them). The PROS Editor still claims that there are some errors about certain definitions not being defined; however the program successfully compiled and uploaded. So, i’m not really sure what that is about. They’re slowly disappearing too.

This is an easy assumption to make. The reality is that #include "file.h" just tells the preprocessor to copy/paste the (preprocessed) content of file.h in place of the #include line itself. This means that in some cases, when this reality is overlooked, you can end up with a situation where include order matters. There are various strategies for avoiding it, but I’m not going to go into it here.

Thanks, that’s very useful to know. I will look more into it.

Glad you solved the problem!
As for the linter problems, they will go away:

The okapi v4 docs are being revamped, but you are right, the okapi lift movement tutorial is misleading and incorrect. Thanks for pointing that out!

1 Like

Would it be of any harm to turn the linter off? I find false information quite annoying, but after reading your reply, I would know how to identify if it was a serious error or not.

Ok thats good to know. Those tutorials would’ve continued to be the end of me otherwise. Glad to know im not just dumb.

The linter just gives you suggestions as you type. It is accurate when it works, and it is obvious when it stops working.
To see if you have a legitimate error, simply compile. That is how you should be checking for errors anyways.
You can turn the linter off, but I wouldn’t as it is still a useful tool that can augment your workflow.