0
$\begingroup$

I have been attempting to have two controllers be able to access information from each other in a way that is similar to object-oriented programming in UNITY, however, I have constantly had problems getting it to work. I always get a similar error of:

Exo_controller.cpp: In function 'int main(int, char**)':
Exo_controller.cpp:22:5: error: expected primary-expression before 'public'
   22 |     public static double dist;
      |     ^~~~~~
Exo_controller.cpp:23:5: error: 'dist' was not declared in this scope
   23 |     dist = distance[1] -> getValue();
      |     ^~~~
Error 1

Could someone explain if it is even possible to have something like object-oriented programming and if not is there anyther way I could simulate this is Webots?

$\endgroup$

2 Answers 2

0
$\begingroup$

In Webots it is not possible to access device values from another robot controller and each controller is running in its own process. See also this question: read-device-value-from-another-robot-controller-in-webots.

So if in your controller program you are trying to get the devices of another robot that it is not the one associated with the current controller instance it won't work.

However, you have some other options to make two Webots controllers communicate with each other:

  1. use the Emitter/Receiver mechanism to send data from one robot/controller the other one
  2. for single values you could also use the Robot.data field to store the data to share and read it in the other controller program using the Supervisor API

Not specific to Webots, you can also use any standard inter-process communication mechanism (files, sockets, shared memory, etc.).

Disclaimer: I am a Webots developer working at Cyberbotics.

$\endgroup$
1
  • $\begingroup$ Thank you very much for the responce, I will try looking into recievers/emitters to see if I could use those! $\endgroup$ Dec 17, 2022 at 21:52
3
$\begingroup$

Welcome to Robotics, Jonathan Ariel Callejas. You haven't provided your code, but I believe the problem you're having is with variable scope.

In your case, your error suggests you're trying to make a public variable that lives inside a method:

In function 'int main(int, char**)': [...] public static double dist;

If the variable is defined inside main, then it can't be public because its scope is limited to main. (Note: It's possible to make a "global" variable, but global variables are never the right answer.)

The compiler is complaining because you're trying to make public static double dist inside main, and it's essentially invalidating that line of code and trying to compile the rest. But, because the declaration isn't valid, when it tries to evaluate the line that uses dist, it doesn't know what dist is and so also throws the second error:

error: 'dist' was not declared in this scope

Easy solution should be to just remove the public keyword, but you can also remove the static keyword because main should be the "outer-most" method; it won't go out of scope (and dist won't get destructed) until the program terminates.

Now, none of this really goes to your comment

I have been attempting to have two controllers be able to access information from each other in a way that is similar to object-oriented programming in UNITY

Unity is C#, and you're writing C++ code, and you can 100% do object-oriented code in both. In C# you can just plop everything in a file and be done with, but in C++ everything has to be declared before you can use it. Typically this is done with a header file, where you might define your class:

public class MyController
{
    public:
        float my_public_float;
        void DoSomethingNeat(float operand);
    private:
        float my_private_float;
};

You then go wherever you've got your main and would include the header, which should generally have the same name as the class inside it, so something like #include<MyController.h>. This tells your program that there is such a thing as a class called MyController, that it has a public float called my_public_float, and a method called DoSomethingNeat that takes a single float as an input, but doesn't return anything.

It doesn't tell the program what those things are, just that they exist. This is kind of the beauty of the header file - you can tuck your definitions away somewhere else, and as long as you don't change the header file, you don't need to rebuild the main program because the interfaces to that class haven't changed.

Then you'd make a .cpp file that actually defines what the class is. That .cpp file would also #include<MyController.h>, and might look something like:

#include<MyController.h>
#include<iostream> // For std::cout
#include<string> // For std::to_string

void MyController::DoSomethingNeat(float operand)
{
    std::cout<<"I was passed: "<<std::to_string(operand)<<std::endl;
}

Any variables that are part of the controller should be made part of the controller class, as public or private depending on whether something outside the class should be able to access it or not, and you can do the same with methods; they can be public/private as well.

All the other object-oriented concepts from Unity/C# apply - inheritance, polymorphism, etc. The syntax is a little different, but you just google the term and "c++" and should get to somewhere like cppreference that explains how to do it in C++.

I'd highly recommend reading some introductory C++ material to familiarize yourself with how concepts like these are implemented in the language.

$\endgroup$

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.