ddemidov / ev3dev-lang-cpp

C++ language bindings for http://ev3dev.org
MIT License
73 stars 38 forks source link

Connecting two large EV3 motors #59

Closed EV3arcanex closed 4 years ago

EV3arcanex commented 4 years ago

Hello! I am searching for a solution to connect two large tacho-motors (EV3). The following part is copied from the YDLidarCar library by Schwaneberg. private: CarControl(); virtual ~CarControl(); ev3dev::large_motor driveMotor; ev3dev::medium_motor steeringMotor;

My attempts to add a second large motor failed. I tried it by calling them by their connected ports:

ev3dev::large_motor leftMotor(ev3dev::outA); ev3dev::large_motor rightMotor(ev3dev::outD);

And I tried it by "auto-detecting":

ev3dev::large_motor leftMotor; ev3dev::large_motor rightMotor;

I don't know any more possibilities.

ddemidov commented 4 years ago

Cat you check the exact address values for the connected motors in /sys/class/tacho-motor/*/address? It is possible that the constants like ev3dev::outA or ev3dev::outD are outdated, so you need to provide those as string literals.

EV3arcanex commented 4 years ago

Thanks for your quick response! I already checked that.. The output of cat sys/class/tacho-motor/motor0/address is: ev3-ports:outA And the definition in the ev3dev.h is: constexpr char OUTPUT_A[] = "ev3-ports:outA"; //!< Motor port A

So I thought that ev3dev::large_motor leftMotor(ev3dev::outA); should work. Is there another way of declaring?

ddemidov commented 4 years ago

Can you try with motor class instead of large_motor?

EV3arcanex commented 4 years ago

I actually don't know what you mean. How would you try to declare that? I have tried: ev3dev::motor leftMotor(ev3dev::outA); and ev3dev::motor rightMotor(ev3dev::OUTPUT_D)

ddemidov commented 4 years ago

I have tried: ev3dev::motor leftMotor(ev3dev::outA);

That is correct:

https://github.com/ddemidov/ev3dev-lang-cpp/blob/6e2ca7e68113f538119a953f6b3bd3f2c9e6e572/ev3dev.h#L582-L593

Did it work?

EV3arcanex commented 4 years ago

No, it didn't.

" In file included from ../CruiseControl.h:11:0, from ../CruiseControl.cpp:8: ../CarControl.h:124:34: error: 'ev3dev::outA' has not been declared ev3dev::motor leftMotor(ev3dev::outA);

"

What I don't understand is that ev3dev::large_motor driveMotor works, but if I want to add a second motor it doesn't. Does it like initialize the same motor twice, when I use ev3dev::large_motor leftMotor ev3dev::large_motor rightMotor ?

ddemidov commented 4 years ago

../CarControl.h:124:34: error: 'ev3dev::outA' has not been declared

Well, there is no such variable. We have these:

https://github.com/ddemidov/ev3dev-lang-cpp/blob/6e2ca7e68113f538119a953f6b3bd3f2c9e6e572/ev3dev.h#L86-L89

So you should try

ev3dev::large_motor left(ev3dev::OUTPUT_A);

or

ev3dev::motor left(ev3dev::OUTPUT_A);

Does it like initialize the same motor twice, when I use

Most probably yes. Unless you specify the address, it uses the * pattern and selects the first motor every time. I can not imagine why the first initialization would work, but the second would not though. What do you mean exactly by "if I want to add a second motor it doesn't"? Is the second motor connected or not?

Another idea: what is the contents of sys/class/tacho-motor/motor0/address/driver_name? Large motor is searching for devices with lego-ev3-l-motor. Is that correct on your system?

https://github.com/ddemidov/ev3dev-lang-cpp/blob/6e2ca7e68113f538119a953f6b3bd3f2c9e6e572/ev3dev.h#L600

Sorry, I have not updated or booted my ev3 for a long time, so I am not sure if there were any breaking changes.

EV3arcanex commented 4 years ago

When I try these

ev3dev::large_motor left(ev3dev::OUTPUT_A); ev3dev::motor left(ev3dev::OUTPUT_A);

the compiler complains: ../CarControl.h:124:29: error: 'ev3dev::OUTPUT_A' is not a type ev3dev::motor left(ev3dev::OUTPUT_A);

The same with large_motor.

Another idea: what is the contents of sys/class/tacho-motor/motor0/address/driver_name? Large motor is searching for devices with lego-ev3-l-motor. Is that correct on your system?

I checked the driver names and the addresses. The addresses and the driver names on the EV3DEV are matching those declared in ev3dev.h.

cat sys/class/tacho-motor/motor0/driver_name lego-ev3-l-motor cat sys/class/tacho-motor/motor2/driver_name lego-ev3-l-motor

cat sys/class/tacho-motor/motor0/address ev3-ports:outA cat sys/class/tacho-motor/motor2/address ev3-ports:outD

What do you mean exactly by "if I want to add a second motor it doesn't"? Is the second motor connected or not?

Yes! There are three motors connected. Two large tacho-motors and a medium one.

ls -l sys/class/tacho-motor/ total 0 motor0 -> ../../devices/platform/ev3-ports/ev3-ports:outA/lego-port/port4/ev3-ports:outA:lego-ev3-l-motor/tacho-motor/motor0 motor1 -> ../../devices/platform/ev3-ports/ev3-ports:outB/lego-port/port5/ev3-ports:outB:lego-ev3-m-motor/tacho-motor/motor1 motor2 -> ../../devices/platform/ev3-ports/ev3-ports:outD/lego-port/port7/ev3-ports:outD:lego-ev3-l-motor/tacho-motor/motor2

ddemidov commented 4 years ago

Yes! There are three motors connected

Sorry, I meant, after you instantiate a large_motor, object, does its connected() method returns true?

https://github.com/ddemidov/ev3dev-lang-cpp/blob/6e2ca7e68113f538119a953f6b3bd3f2c9e6e572/ev3dev.h#L101

../CarControl.h:124:29: error: 'ev3dev::OUTPUT_A' is not a type ev3dev::motor left(ev3dev::OUTPUT_A);

Can you just try

ev3dev::motor left("ev3-ports:outA");
ev3dev::motor right("ev3-ports:outD");

std::cout << "left: " << left.connected()
          << " right: " << right.connected() << std::endl;

?

EV3arcanex commented 4 years ago

Maybe this is a misunderstanding but when I declare:

ev3dev::motor left("ev3-ports:outA"); ev3dev::motor right("ev3-ports:outD");

the compiler won't get over this point.

But to add something: The declaration of the motors is done in the CarControl.h. CarControl.h is included in the CarControl.cpp and in the cpp-file it says:

    bool success = true;
if (leftMotor.connected() && rightMotor.connected())
{
     leftMotor.reset();
     rightMotor.reset(); }

And the car won't start up unless they are connected successful. And of course this works if the same motor is declared as left and right motor (by using ev3dev::large_motor).

Maybe the link to this repository may be helpful. So here it is: https://github.com/Schwaneberg/YDLidarCar

I barely changed anything. I am just trying to add the second motor.

ddemidov commented 4 years ago

This does look like a misunderstanding. I don't know where the CarControl files are coming from. The declaration in this library are contained in ev3dev.h/ev3dev.cpp.

You could try to compile demo/drive-test.cpp from this library to see if it works with your motors.

EV3arcanex commented 4 years ago

I have not explicitly said that, but the project I am working on is using your C++ library. So the CarControl files are part of the program that runs the EV3. In the CarControl.h the ev3dev.h in included. So the declaration of the motors should follow the rules and syntax declared in your library. The demo/drive-test.cpp runs without any problems.

ddemidov commented 4 years ago

Is it possible the ev3dev.h and ev3dev.cpp files that come with CarControl are outdated or modified? For example, the fact that the compiler does not know about ev3dev::OUTPUT_A constant or the motor class makes me think so. Here are sha1 checksums for the current files:

$ sha1sum ev3dev.h ev3dev.cpp 
d7ef80c2beabf7d73837dd1523d00cdd33eea318  ev3dev.h
ab12fb181246e5559573da26efe0d70fbd6c978e  ev3dev.cpp

The demo/drive-test.cpp runs without any problems.

Maybe you could compare the motor initialization code from CarControl with that of drive-test.cpp:

https://github.com/ddemidov/ev3dev-lang-cpp/blob/6e2ca7e68113f538119a953f6b3bd3f2c9e6e572/demos/drive-test.cpp#L79-L80

EV3arcanex commented 4 years ago

I am sorry for taking so much of your time! But you gave me a tip and I just realised my fault! It is now working!

In the CarControl.h I declared:

ev3dev::large_motor leftMotor; ev3dev::large_motor rightMotor;

And in the CarControl.cpp which includes the CarControl.h:

CarControl::CarControl() : leftMotor(ev3dev::OUTPUT_A), rightMotor(ev3dev::OUTPUT_D)

Silly mistake, but it the end I am happy that it works now. Thanks so much for your help!