Error when compiling with GoPiGo3. cpp

I’m trying to compile a c++ program for my GoPiGo3. It’s a simple program where the user can input wasd from the keyboard and then it will execute the piece of code to move in a certain direction.
I compile using the following command: g++ -o test Robots.cpp GoPiGo3.cpp -I .
I have Robots.cpp, GoPiGo3.cpp and GoPiGo3.h in the same folder on my desktop.
I get the following errors:

/tmp/cc3Z7gQv.o:(.data+0x0): multiple definition of `spi_file_handle'
/tmp/cctmOpje.o:(.data+0x0): first defined here
/tmp/cc3Z7gQv.o:(.bss+0x0): multiple definition of `spi_xfer_struct'
/tmp/cctmOpje.o:(.bss+0x0): first defined here
/tmp/cc3Z7gQv.o:(.bss+0x20): multiple definition of `spi_array_out'
/tmp/cctmOpje.o:(.bss+0x20): first defined here
/tmp/cc3Z7gQv.o:(.bss+0x48): multiple definition of `spi_array_in'
/tmp/cctmOpje.o:(.bss+0x48): first defined here
/tmp/cc3Z7gQv.o: In function `spi_setup()':
GoPiGo3.cpp:(.text+0x0): multiple definition of `spi_setup()'
/tmp/cctmOpje.o:Robots.cpp:(.text+0x0): first defined here
/tmp/cc3Z7gQv.o: In function `spi_transfer_array(unsigned char, unsigned char*, unsigned char*)':
GoPiGo3.cpp:(.text+0x84): multiple definition of `spi_transfer_array(unsigned char, unsigned char*, unsigned char*)'
/tmp/cctmOpje.o:Robots.cpp:(.text+0x84): first defined here
/tmp/cc3Z7gQv.o: In function `fatal_error(char const*)':
GoPiGo3.cpp:(.text+0x124): multiple definition of `fatal_error(char const*)'
/tmp/cctmOpje.o:Robots.cpp:(.text+0x124): first defined here
/tmp/cc3Z7gQv.o:(.bss+0x70): multiple definition of `_time'
/tmp/cctmOpje.o:(.bss+0x70): first defined here
/tmp/cc3Z7gQv.o: In function `get_time()':
GoPiGo3.cpp:(.text+0x174): multiple definition of `get_time()'
/tmp/cctmOpje.o:Robots.cpp:(.text+0x174): first defined here
collect2: error: ld returned 1 exit status

This is my code:

#include <GoPiGo3.h>   // for GoPiGo3
#include <stdio.h>     // for printf
#include <unistd.h>    // for usleep
#include <signal.h>    // for catching exit signals
 

#define NO_LIMIT_SPEED 1000

GoPiGo3 GPG; 

void exit_signal_handler(int signo);

int main(){
	
	signal(SIGINT, exit_signal_handler); // register the exit function for Ctrl+C
	
	GPG.detect();
	
	char c = getchar();
	//printf("Char: %c", c);
		
	switch(c){
		case 'w':
			GPG.set_motor_dps(MOTOR_LEFT + MOTOR_RIGHT, NO_LIMIT_SPEED);
			break;
		case 's' :
			GPG.set_motor_dps(MOTOR_LEFT + MOTOR_RIGHT, NO_LIMIT_SPEED * -1);
			break;
		case 'd' :
			GPG.set_motor_dps(MOTOR_LEFT, NO_LIMIT_SPEED);
			GPG.set_motor_dps(MOTOR_RIGHT, 0);
			break;
		case 'a' : 
			GPG.set_motor_dps(MOTOR_LEFT, 0);
			GPG.set_motor_dps(MOTOR_RIGHT, NO_LIMIT_SPEED);
			break;
		case 'q' : 
			GPG.set_motor_dps(MOTOR_LEFT + MOTOR_RIGHT, 0);
			break;
	} 
} 	
	
	
void exit_signal_handler(int signo){
	  if(signo == SIGINT){
         GPG.reset_all();    // Reset everything so there are no run-away motors
         exit(-2);
	  }
} 

What am I doing wrong?

1 Like

I created /home/pi/Carl/Examples/cpp
then copied the cpp examples there:

cp -r /home/pi/Dexter/GoPiGo3/Software/C/* cpp

From /home/pi/Carl/Examples/cpp, I get the same errors as OP for
g++ -o motors motors.cpp …/GoPiGo3.cpp -I… (from the motors.cpp file header)

BUT THE FOLLOWING WORKED!!!

I installed cmake (sudo apt-get install cmake)
and ran

pi@Carl : ~/Carl/Examples/cpp $ cmake CMakeLists.txt
– The C compiler identification is GNU 6.3.0
– The CXX compiler identification is GNU 6.3.0
– Check for working C compiler: /usr/bin/cc
– Check for working C compiler: /usr/bin/cc – works
– Detecting C compiler ABI info
– Detecting C compiler ABI info - done
– Detecting C compile features
– Detecting C compile features - done
– Check for working CXX compiler: /usr/bin/c++
– Check for working CXX compiler: /usr/bin/c++ – works
– Detecting CXX compiler ABI info
– Detecting CXX compiler ABI info - done
– Detecting CXX compile features
– Detecting CXX compile features - done
– Configuring done
– Generating done
– Build files have been written to: /home/pi/Carl/Examples/cpp

Next I typed:

make
Scanning dependencies of target gopigo3
[ 7%] Building CXX object CMakeFiles/gopigo3.dir/GoPiGo3.cpp.o
[ 14%] Linking CXX shared library libgopigo3.so
[ 14%] Built target gopigo3
Scanning dependencies of target i2c
[ 21%] Building CXX object CMakeFiles/i2c.dir/Examples/i2c.cpp.o
[ 28%] Linking CXX executable i2c
[ 28%] Built target i2c
Scanning dependencies of target grove_led
[ 35%] Building CXX object CMakeFiles/grove_led.dir/Examples/grove_led.cpp.o
[ 42%] Linking CXX executable grove_led
[ 42%] Built target grove_led
Scanning dependencies of target motors
[ 50%] Building CXX object CMakeFiles/motors.dir/Examples/motors.cpp.o
[ 57%] Linking CXX executable motors
[ 57%] Built target motors
Scanning dependencies of target info
[ 64%] Building CXX object CMakeFiles/info.dir/Examples/info.cpp.o
[ 71%] Linking CXX executable info
[ 71%] Built target info
Scanning dependencies of target sensors
[ 78%] Building CXX object CMakeFiles/sensors.dir/Examples/sensors.cpp.o
[ 85%] Linking CXX executable sensors
[ 85%] Built target sensors
Scanning dependencies of target leds
[ 92%] Building CXX object CMakeFiles/leds.dir/Examples/leds.cpp.o
[100%] Linking CXX executable leds
[100%] Built target leds

voila! the executables are made, and typing ./motors ran the program.

So @froggyfreshrap, try what I did (copy the examples, install cmake, run cmake, run make)

Now that libgopigo3.so is built the following will compile but the executable complains (in Examples/cpp/Examples):

g++ -o motors motors.cpp …/libgopigo3.so -I…

(Perhaps need to either add robots to CMakeLists.txt or create a “MyCMakeLists.txt” - I’m not sure what is the correct approach — actually, I’m sticking with Python - that seems to be the recommended approach!)

(Additionally, if you are using git, some .gitignore entries need to be set up and perhaps the executables need to go in a “out/” folder so your git status will not constantly show a pile of untracked files.)

What I did:

  • mkdir /home/pi/Carl/Examples/cpp/robots

  • put my robot.cpp in cpp/robots/ folder
    (added loop and mapped s,x, and spacebar keys)

  • added my target to the CMakeLists.txt

# robot
add_executable(robot robots/robot.cpp)
target_link_libraries(robot gopigo3)
  • cmake CMakeLists.txt
  • make
  • ./robot

Summary here: Alan_Notes.txt

1 Like

Thank you very much for your extensive answer!
I’ll have my hands back on the robot tomorrow, so I’ll try it out then :slight_smile:
I’ll let you know how it goes.

1 Like

I have successfully compiled the program without any errors (added Robots.cpp to CmakeListstxt and did cmake. and make). I run ./robot and when I try to control the robot with the keyboard buttons, unfortunately nothing happens. I see the keyboard buttons pressed in the terminal but the robot won’t move. I added the loop just like you did (see code below). The GoPiGo3 control panel on the desktop works successfully, the robots will move in the pressed directions.What am I doing wrong?

#include <GoPiGo3.h>   // for GoPiGo3
#include <stdio.h>     // for printf
#include <unistd.h>    // for usleep
#include <signal.h>    // for catching exit signals
 

#define NO_LIMIT_SPEED 1000

GoPiGo3 GPG; 

void exit_signal_handler(int signo);

int main(){
	
	signal(SIGINT, exit_signal_handler); // register the exit function for Ctrl+C
	
	GPG.detect();
	
	bool keepLooping = true;
	
	do{
		char c = getchar();
		//printf("Char: %c", c);
		
		switch(c){
			case 'w':
				GPG.set_motor_dps(MOTOR_LEFT + MOTOR_RIGHT, NO_LIMIT_SPEED);
				break;
			case 's' :
				GPG.set_motor_dps(MOTOR_LEFT + MOTOR_RIGHT, NO_LIMIT_SPEED * -1);
				break;
			case 'd' :
				GPG.set_motor_dps(MOTOR_LEFT, NO_LIMIT_SPEED);
				GPG.set_motor_dps(MOTOR_RIGHT, 0);
				break;
			case 'a' : 
				GPG.set_motor_dps(MOTOR_LEFT, 0);
				GPG.set_motor_dps(MOTOR_RIGHT, NO_LIMIT_SPEED);
				break;
			case 'q' : 
				GPG.set_motor_dps(MOTOR_LEFT + MOTOR_RIGHT, 0);
				keepLooping = false;
				break;
			case ' ' : 
				GPG.set_motor_dps(MOTOR_LEFT + MOTOR_RIGHT, 0);
				break;
		}  
	} while (keepLooping);	
} 	
	
	
void exit_signal_handler(int signo){
	  if(signo == SIGINT){
         GPG.reset_all();    // Reset everything so there are no run-away motors
         exit(-2);
	  }
} 

terminal

1 Like

Congratulations on getting your program to executable state.

(I am a GoPiGo3 bot user, like yourself, and not affiliated with Dexter Industries. I believe Dexter Industries recommends, and focuses their support on, programming the GoPiGo3 in either Python or Bloxter. You may be headed over uncharted waters in C++.)

That said, your C++ program did drive my GoPiGo3 so I suggest running the “info” program that was also compiled by the CMake/make sequence:

pi@Carl:~/Carl/Examples/cpp/out $ ./info

GoPiGo3 info:
Manufacturer : Dexter Industries
Board : GoPiGo3
Serial Number : BA93E*************************
Hardware version: 3.x.x
Firmware version: 1.0.0
Battery voltage : 9.046
5v voltage : 5.065

If your Battery voltage is low, that could prevent your bot from moving.

Do these other examples work?

  • ./leds should cycle the programmable color LEDs
  • ./motors should drive the bot forward and print the encoder values on your terminal

You mention the desktop, so I will guess you are in RaspianForRobots. Since you said the control panel drives the bot, I’m totally at a loss.

1 Like

I ran the info program and I get the following output:

GoPiGo3 info:
  Manufacturer    : Dexter Industries
  Board           : GoPiGo3
  Serial Number   : 0D9DAA
  Hardware version: 3.x.x
  Firmware version: 1.0.0
  Battery voltage : 10.339
  5v voltage      : 5.121

When I run ./leds the LEDS are being cycled successfully. When I run ./motors nothing happens. I only get an output with 0.
terminal%20output

When I run the GoPiGo3 application on the Desktop and press any of the direction buttons, the robot starts to move in the pressed direction. I also ran he Test and Troubleshoot program you mentioned and did the Demo, the robot successfully completes the demo and moves forward and backwards. What could the issue be?
Does maybe a certain hardware option be enabled to make the motors work in C/C++?? I2C? SPI?

I just checked the description of ./motors on Dexter Industries Github and it says the following:
Results: When you run this program, you should see the encoder value for each motor. Manually rotate the left motor, and the right motor will follow.

Is it supposed to move forward? It says manually, I can manually turn the left wheel and the values will be printed out for both the left and the right.

Just reran ./motors and you are correct, it does not drive forward. Twisting the left (looking from rear) wheel a little will move the right wheel. Both encoder values change when I twist the left wheel a little forward or backward.

Other than the classic “when all else fails, try cycling the power”, I’m out of ideas for you to try. Sorry.

p.s. Try adding a cout or printf statement to each switch case in your program to absolutely rule out a problem with your program e.g.: printf(“Forward\n”);

1 Like

Thanks for the reply!
I’ll try out the print statement tomorrow and let you know. I really need to get this to work as this is part of my graduation internship, I hope I can figure it out. Did you by any chance maybe enable certain hardware settings (somewhere in the past) ? Maybe that’s why it works for you and not for me?

I think R4R had everything already enabled, and the fact that running the info.cpp successfully means SPI is enabled and working.

The fact that your “demo” button worked might imply a GoPiGo3.cpp software version issue but I don’t think that code has changed since Feb 2018. You could try the update icon on the desktop (with fresh charge or connected to USB power), to be sure.

I don’t know how to diagnose this issue properly.

@RobertLucian: any tips?

Never forget that a good write-up of what worked and what didn’t, with what you tried for diagnosing the issue is strong evidence of learning. Getting it working is only one way to demonstrate what you learned.

There isn’t a particular reason why his code wouldn’t work. The GoPiGo3’s library has changed quite a lot and I doubt we did any changes to the underlying communication protocol between the Pi and the GoPiGo3.

As of this moment, I’m not exactly sure what’s the reason. I will though, try this thing on mine and see what’s wrong with it. Expect an answer from me.

Thank you!

I tried executing the code with a print statement. No text is being printed out when i press “w”.
This is how the piece of code looks like:

switch(c){
			case 'w':
				printf("Forward\n");
				GPG.set_motor_dps(MOTOR_LEFT + MOTOR_RIGHT, NO_LIMIT_SPEED);

I just ran the BasicRobotControl Python program in the Projects folder and it also runs fine. I’m controlling the GoPiGo3 from dex.local with the VNC option. This is the version I am running:
Linux dex 4.19.42-v7+ #1219 SMP Tue May 14 21:20:58 BST 2019 armv7l GNU/Linux

Did you try pressing “return” after the “w”?

3 Likes

Oh wow! That was the issue, when I press Enter after I have pressed “w”, the robot will move forward. Thank you very much for the help! Do you know if there is a way for the robot to move immediately forward without the Enter button?

1 Like
1 Like

Thank you very much, I got it to work! :slight_smile:

1 Like

For future C/C++ users:

If you follow this thread, you should be able to build your executable.

Afterwards, it would be of great help to the community if you would investigate the following (GoPiGo version 1) document to decide the changes needed for GoPiGo3: