Programming 3pi robot in linux

I’m not entirely sure if this is the correct forum for my question. If it’s not, please accept my apology and hopefully one of the friendly administrators could kindly move it to the proper forum. I’m frustrated. I own a computer that does not have the windows operating system on it. I solely run Ubuntu 14.10, and it has been frustrating to me to program my 3pi robot in linux. I did find and sucessfully followed instructions from this website to install avrdude and the Pololu libraries on my computer. I’m able to sucessfully compile, transfer, and run any of the 3pi sample projects from the Examples folder.
ok, so here’s my problem:
I am a inexperienced programmer, I’ve only written very small programs on my computer in the c language, and the Arduino language. When coding Arduino sketches, I use the Arduino IDE, when coding in c, I use the Eclipse IDE. I’ve also written small programs in c at the command prompt, using VIM.
I want to create my own programs to run on my 3pi robot, I just ordered a 3pi expansion kit to help with that task. The thing I’m not understanding are the different files that are in the Pololu example directory. I’ve only created my own .c files, the other files in those directories are a Makefile, an .aps file, an atsln file, and a cproj file. some of these files I suspect are from AVR studio files. I don’t have AVR studio on my computer, nor can I find a recent walkthrough to install it. What are my options to Author files in Ubuntu that I can compile and run on my little 3pi powerhouse? My goal is to add my Arduino 2560 to my 3pi in a master/slave configuration to control an robotic arm I have built. Leaving the locomotion and navigation up to the 3pi, and using the 2560 to operate the robotic arm. I dont have it completely figured out how I will acomplish this, but if I could get some direction/advise on beginning to author my programs for the 3pi.

Hello.

You are correct that .aps, .atsln, and .cproj files that come with the examples in the Pololu AVR Library are associated with AVR (or Atmel) Studio. Those files will not be useful to you on Linux. Each example comes with a Makefile that you can use to compile your program. The Makefile is basically a file that contains rules to create files from other files. If you open a terminal (and go to that directory) and type " make", your program will be compiled. For more information, you can look at the “Programming in Linux” section of the AVR Programming Quick Start Guide.

Since you are new to programming and want to write your own program, the easiest way to get started is to compile one of the example programs in the library and then start modifying it to make it do what you want. You can use the 3pi’s serial pins (PD0 and PD1) to connect your Arduino to it and send serial commands from your Arduino to control your 3pi. You might find our serial slave program helpful. You can look at the “Serial slave program” section of the 3pi user’s guide for more information. With the serial slave program loaded onto the 3pi, you can send commands to control various features of the 3pi. Since the serial master program is not meant to run on an Arduino, you will need to write your own code for it. You can refer to the commands listed in the “Serial slave program” section to see what commands you need to send from your Arduino to your 3pi.

Since you are familiar with using the Arduino IDE, you might consider looking at the Programming Orangutans and the 3pi Robot from the Arduino Environment guide. Also, you might find this visual programming tool for our 3pi useful.

- Amanda

Awesome,I was able to write a small program, I was able to compile it and run it in Linux, thanks for the help. There was some unexpected behavior from the 3pi when I ran the program though. Here’s my .c file. I expected it to play the c scale, turn on both leds, spin in one direction, then stop and spin in the other direction. It’s a simple program. I just wanted motor1 to spin forward, and motor 2 spin in reverse. Stop the motors. Then motor1 to spin reverse, and motor 2 spin forward. But, it seems to only spin in one direction. Maybe I don’t understand how the set_motors function works. What did I do wrong?

[code]//============================================================================
// Name : myprogram.c
// Author :
// Version :Your version number here
// Copyright : Your copyright notice here.
// :
// Description : My first program in c programming my 3pi robot in linux.
// Compiler :gcc (Ubuntu 4.8.2-19ubuntu1) 4.8.2
//============================================================================
#include <pololu/orangutan.h>
int main()
{

play("!L16 V8 cdefgab>cbagfedc"); //play c scale
delay(2000); //Wait 2 seconds
red_led(1); //turn on red led
green_led(1); //turn on green led
set_motors(-255,255); //spin left
delay(2000); //Wait 2 seconds
set_motors(0,0); //stop motors
set_motors(255,-255); //spin right
delay(2000); //Wait 2 seconds
set_motors(0,0); //stop motors
return 0;
}[/code]
UPDATE: i finally got the 3pi to spin as I expected by lowering the speeds to 100. I’m still unable to get the 3pi to wait until a button is pressed before beginning to move with this code: print("Press B to start"); wait_for_button_release(BUTTON_B);
I would like to have my hand away from the robot before it starts moving. Thanks again.

Could you post the code you are currently using that has the wait_for_button_release function in it?

- Amanda

I’m embarressed now. While I was copieng my code to paste, I noticed that I made a comment prior to that section /* and my comment was not closed intil the next instruction. So, the compiler ignored that section of my code. I know better than that. GRRRRR.

It is not clear to me if you fixed your issue or not, but thinking about it again, it seems like you should be using waitForButton instead of wait_for_button_release. If you call wait_for_button_release without checking for a button pressed event and the default state of your button is not pressed, the function will return quickly; since your program is short, you would probably need to be holding down the button when the program starts up to get it to wait using that command. The waitForButton function waits for the specified button to be pressed and release before continuing on. For more information on that command, see Section 9 of the command reference.

- Amanda

[quote]it seems like you should be using waitForButton]instead of wait_for_button_release. [/quote] It seems to be working well for me. I used an example I got from this website. Here is the link to it. [url]https://www.pololu.com/docs/0J20/3.g[/url]. I'm happy to know about the waitForButton function also. I’m excited about adding new tools to my programming toolbelt. Here is the latest version of my program, [code]//============================================================================
// Name : myprogram.c
// Author :
// Version :Your version number here
// Copyright :Your copyright notice here.
// :
// Description : My first program in c programming my 3pi robot in linux.
// Compiler :gcc (Ubuntu 4.8.2-19ubuntu1) 4.8.2
//============================================================================
#include <pololu/orangutan.h>
#include <pololu/3pi.h>

int main()
{
//display 3pi robot
print(“3\xf7 robot /n”);
delay(2000);
//display voltage to make sure it’s safe to program
while(!button_is_pressed(BUTTON_B))
{
int bat = read_battery_millivolts();
if (bat < 4300)
{
print(“low volt”);
break;
}
clear();
print_long(bat);
print(“mV”);
lcd_goto_xy(0,1);
print(“Press B”);
delay_ms(100);
}
wait_for_button_release(BUTTON_B);
delay_ms(1000);
clear();
print(“Go!”);

play(“L16 cdegreg4”); //play “go” tune
delay(2000); //Wait 2 seconds
red_led(1); //turn on red led
green_led(1); //turn on green led
set_motors(-200,200); //spin left
delay(5000); //Wait 2 seconds
set_motors(0,0);
delay(500); //stop motors
set_motors(200,-200); //spin right
delay(5000); //Wait 2 seconds
set_motors(0,0); //stop motors
clear();
}
[/code]
I’ve successfully programmed it to spin in place. I’ve installed the expansion kit, along with a GP2Y0A21YK0F sharp IR sensor. I know it’s not an ideal sensor for the job, but I had it left over from another project.


I’ve removed the trim pot jumper and connected my Sharp sensor to ADC7, so I was able to test the sensor by loading the analog1 example, and observed the brightness of the red LED as I placed objects in front of the robot. My next mission is to somehow modify the analog1 example so the ADC7 output displays as a decimal number on my LCD screen. I like the idea of using the LCD screen to monitor variables while the program is running, it makes troubleshooting easier. My goal is eventually be able to make an obstacle course for the 3pi. I’d like to learn more about robot mapping algorithms.

need help with my sharp ir test code. I have a small program to test my sharp ir sensor that is not working. I had good readings from the sensor with the first 12 lines of this program. My distance numbers ranged from 3 to about 630 as I moved objects in front of the robot. the part of the program that does not work is after line 12. I am attempting to make the motors respond to the sensor readings. I am a novice at programming, but I don’t understand why my simple program does not deliver expected results. I’m simply reading the sensor and spinning the motors based on the sensor level. but the robot does not move at all. the only change I’ve made to my hardware is I’ve added a 10microfarad capacitor between ground and vcc to save the batteries from voltage spikes. Can you tell me whats wrong with my code?

[code]
#include <pololu/3pi.h>

unsigned int dis;
int main()
{

dis=(analog_read(7));
{
print_long(dis);
print(" distance"); // print distance
lcd_goto_xy(0,0);
}
while(1);

if  (dis>600)                 //if an object is too close, spin for a new direction

{
set_motors(-25,25);
delay(1000);
set_motors(0,0);
delay(1000);
}

if  (dis<  600)
{
set_motors(50,50); //if direstion is clear go forward
}
                  
if  (dis>  600)
{                     
   set_motors(0,0);  //if object is too close stop motors
delay(1000);

}

}[/code]

I looked at your code briefly and noticed you have an infinite loop, which might be causing the problem. When an infinite loop such as while(1) starts, the code after the loop never runs unless you forcefully exit out of that loop using break. If you are trying to run a segment of code continuously, then you would need to enclose the relevant code within braces. For example:

while(1)
{ //<--Opening brace
   // Continuously read sensor and move motors based on those readings
   delay(1000);
} //<--Closing brace

Also, it looks like you have an extra pair of curly braces in your code (after dis=(analog_read(7)); and before while(1);). I do not know the purpose of those extra braces, but they are not necessary and should be removed from the code.

- Amanda