Hi everyone! I'm working on a robot project, and I'm having trouble with the processing code running on the computer on the robot. It communicates with the micro-controller through com4, a gps on com5, and with a client program running on my laptop through a VPN port. I'm trying to add a window that reads the camera and does some basic red color object detection. The code in the PApplet was originally a separate program, and was working fine, I am trying to migrate it into the main program running on the robot. Run it and see where it error's out. It seems it's confused about which window to read pixels from. You only need a USB (or built in) camera hooked up to run this (and work eventually hopefully). Can someone explain how to choose which window to read the pixel from? Also, I intend on adding a 3rd window displaying a grey scale of ratings of where the robot plans to move, and a 4th window which will be the main control window (pulling the text info out of the sonar window). If it helps I can post the working object detection code separately. Much appreciated!
- import processing.serial.*; //serial port read library
- import processing.net.*;
- UIWindow uiWindow;
- Server myServer;
- int serverport = 1234;//port used to communicate with clients over Hamachi
- Serial com5;
- Serial com4;
- String dataincom4, dataoutcom4, dataincom5;
- Float Latitude1 = 0.0, Latitude2 = 0.0;
- String Latitude;
- String NorSindicator;
- Float Longitude1 = 0.0, Longitude2 = 0.0;
- String Longitude;
- String EorWindicator;
- String Satellites;
- String Altitude;
- String gpsdata, gpsdata2;
- Float Speed1 = 0.0, Heading1 = 0.0;
- String Speed, Heading, Lock;
- int Lock1 = 0, Satellites1 = 0;
- Float firstLat = 0.0, firstLon = 0.0;
- int px = 0, py = 0;
- int[] keys = new int[256];
- String dataCode1, dataCode2;
- Float indata;
- Float ardposx, ardposy, ardheading, ardcompass, ardheaddraw, ardheaddraw2;
- int sonarinchL1, sonarinchR1, sonarinchL2, sonarinchR2;
- Float sx, sy, sxp, syp;
- int mpltimer;
- float beamwidth = 0.08;
- import processing.video.*;
- Capture myCapture;
- void setup(){
- frame.setTitle("Sonar Map");
- myServer = new Server(this, serverport);
- size(800,600); //window size
- //frameRate(10);
- PFont myFont = createFont(PFont.list()[2],16); // font type
- textFont(myFont);
- background(255, 255, 255);
- stroke(0,0,0);
- //smooth();
- println(Serial.list()); // displays port numbers for program
- com5 = new Serial(this, "COM5", 9600); // serial read setup
- com5.bufferUntil('\r'); // library buffer
- com4 = new Serial(this, "COM4", 9600); // serial read setup
- com4.bufferUntil(10); // library buffer
- ardheaddraw = 0.0;
- ardheaddraw2 = 0.0;
- ardposx = 0.0; ardposy = 0.0;
- com4.write("<0.0I0>");//request x and y position
- mpltimer = millis();
- uiWindow = new UIWindow();
- }
- void draw(){
- fill(255, 255, 255);
- rect(0, 0, 200, 600);//clear left text area for new text
- fill(0, 0, 0);
- stroke(0,0,0);
- //window display
- textAlign(LEFT);
- text(" Latitude: " + Latitude, 10, 10);
- text(" Longitude: " + Longitude, 10,30);
- text(" Position: " + NorSindicator + " " + EorWindicator, 10,50);
- text(" Positive Lock: " + Lock, 10,70);
- text(" Satellites Used: " + Satellites, 10,90);
- text(" Altitude: " + Altitude + " Meters", 10,110);
- text(" Speed: " + Speed, 10, 130);
- text(" Heading: " + Heading1, 10, 150);
- text(" Data from Arduino", 10, 310);
- text(" PosX: " + ardposx, 10, 330);
- text(" PosY: " + ardposy, 10, 350);
- text(" Sonar L2: " + sonarinchL2, 10, 370);
- text(" Sonar L1: " + sonarinchL1, 10, 390);
- text(" Sonar R1: " + sonarinchR1, 10, 410);
- text(" Sonar R2: " + sonarinchR2, 10, 430);
- text(" Heading: " + ardheading, 10, 450);
- text(" Compass: " + ardcompass, 10, 470);
- line(160, 430, 160, 430 - sonarinchL2);
- line(170, 430, 170, 430 - sonarinchL1);
- line(180, 430, 180, 430 - sonarinchR1);
- line(190, 430, 190, 430 - sonarinchR2);
- fill(255,255,255);
- ellipse(180, 450, 30, 30);
- fill(0,0,0);
- //arc(180, 450, 30, 30, ardheaddraw2 + 0.5, ardheaddraw2 - 0.5);
- line(180, 450, cos(ardheaddraw2) * 15 + 180, sin(ardheaddraw2) * 15 + 450);
- //text(" GPS unparsed: " + gpsdata, 20,170);
- //text(" GPS unparsed: " + gpsdata2, 20,190);
- // draw points where sonars detect objects
- //fill(255, 0, 0);
- //point((ardposx + 500)
- if (mousePressed && mouseButton == LEFT){
- point(mouseX, mouseY);
- }
- if (firstLat == 0.0 && firstLon == 0.0){
- if (Latitude1 != 0.0 && Longitude1 != 0.0){
- if (Satellites1 >= 3 && Lock1 >= 1){
- firstLat = Latitude1 * 1000000.0;
- firstLon = Longitude1 * 1000000.0;
- }
- }
- }
- if (firstLat != 0.0 && firstLon != 0.0){
- py = int((firstLat - (Latitude1 * 1000000.0)) + (width / 2.0));
- px = int((firstLon - (Longitude1 * 1000000.0)) + (width / 2.0));
- //ellipse(px, py, 2, 2);
- }
- //Get the next available client
- Client thisClient = myServer.available();
- //If the client is not null, and says something, display what it said
- try {
- if (thisClient != null) {
- String clientindata = thisClient.readStringUntil('\n');
- if (clientindata != null) {
- com4.write(trim(clientindata));//forward client data to Arduino
- println(thisClient.ip() + " : " + clientindata);
- }
- }
- }catch(Exception e) {
- println("Client port error");
- //decide what to do here for the error
- }
- print("MPL:"); println(millis() - mpltimer);
- mpltimer = millis();
- }
- //camera object detection applet
- public class UIWindow extends PApplet {
- Frame frame;
- int width = 320;
- int height = 240;
- //camera object detect applet init
- import processing.video.*;
- Capture myCapture;
- PImage img;
- int w = 80, pixdetect = 0;
- int objx1, objx2, objy1, objy2;
- UIWindow ()
- {
- width = 320;
- height = 240;
- frame = new Frame();
- frame.setBounds(0, 0, width, height);
- frame.add(this);
- this.init();
- frame.show();
- frameRate(30);
- }
- void setup() {
- size(320, 240);
- frameRate(30);
- myCapture = new Capture(this, 320, 240, 1);
- myCapture.frameRate(30);
- frame.setTitle("Camera object detect");
- }
- void draw() {
- int[][] obj = new int[320][240];
- if(myCapture.available()) {
- myCapture.read();
- image(myCapture, 0, 0);
- img = myCapture;
- }
- objx1 = 160; objx2 = 160; objy1 = 120; objy2 = 120;
- loadPixels();
- // Begin loop for every pixel
- for (int x = 1; x < width; x++) {
- for (int y = 1; y < height; y++ ) {
- color c = detection(x,y,img);
- int loc = x + y*320;
- pixels[loc] = c;
- obj[x][y] = pixdetect;
- }
- }
- updatePixels();
- //Begin search for objects
- for (int x = 2; x < 320 - 1; x++) {
- for (int y = 2; y < 240 - 1; y++ ) {
- if (obj[x][y] == 1 && obj[x+1][y] == 1 && obj[x-1][y] == 1 && obj[x][y+1] == 1 && obj[x][y-1] == 1) {
- if (x > objx1 && objx1 == int(width/2)) objx1 = x;
- if (x < objx2 && objx2 == int(width/2)) objx2 = x;
- if (x > objy1 && objy1 == int(height/2)) objy1 = y;
- if (x > objy2 && objy2 == int(height/2)) objy2 = y;
- if (x < objx1) objx1 = x;
- if (x > objx2) objx2 = x;
- if (y < objy1) objy1 = y;
- if (y > objy2) objy2 = y;
- }
- }
- }
- stroke(255,0,0);
- rect(objx1, objy1, objx2 - objx1, objy2 - objy1);
- stroke(0);
- noFill();
- //rect(xstart,ystart,w,w);
- }
- color detection(int x, int y, PImage img) {
- // What pixel are we testing
- int loc = x + 320*y;
- // Make sure we have not walked off the edge of the pixel array
- loc = constrain(loc,1,76799);
- float r = red(pixels[loc]);
- float g = green(pixels[loc]);
- float b = blue(pixels[loc]);
- float br = brightness(pixels[loc]);
- float sa = saturation(pixels[loc]);
- if (br + sa > 255.0 && r > 70.0 && r > g + 40.0 && r > b + 40.0 && g - b < 30.0 && g - b > -30.0) {
- r = 255.0; g = 0.0; b = 0.0;
- pixdetect = 1;
- }else {
- pixdetect = 0;
- //r = 0.0; g = 0.0; b = 0.0;
- }
- // Return the resulting color
- return color(r,g,b);
- }
- }
- //end camera object detect applet
- // function reads the gps or Arduino data and sends it to the parsing function
- void serialEvent(Serial thisPort) {
- try {
- if (thisPort == com5){
- String dataincom5 = com5.readStringUntil('\n');
- if (dataincom5 != null) {
- //println("com5:");
- //println(dataincom5);
- myServer.write(trim(dataincom5) + ", com5\n");//forward data to client
- parseStringcom5(dataincom5);
- }
- }
- if (thisPort == com4){
- String dataincom4 = com4.readStringUntil('\n');
- if (dataincom4 != null) {
- //println("com4:");
- //println(dataincom4);
- myServer.write(trim(dataincom4) + ", com4\n");//forward data to client
- parseStringcom4(dataincom4);
- }
- }
- }catch(Exception e) {
- println("Com port error");
- //decide what to do here for the error
- }
- }
- //parse com4 Arduino
- void parseStringcom4 (String serialString) {
- String[] list = split(serialString, ',');
- indata = float(list[0]);
- dataCode1 = list[1];
- dataCode2 = list[2];
- //println(indata);
- //println(dataCode1);
- //println(dataCode2);
- if (dataCode1.equals("L") && dataCode2.contains("1")){
- sonarinchL1 = int(indata);
- sx = (500 + ardposx) + (cos(ardheaddraw + 0.5) * 15.0);
- sy = (300 - ardposy) - (sin(ardheaddraw + 0.5) * 15.0);
- sxp = sx + (cos(ardheaddraw) * sonarinchL1);
- syp = sy - (sin(ardheaddraw) * sonarinchL1);
- stroke(200,255,255,63); fill(200,255,255,63);
- line(sx, sy, sxp, syp);
- stroke(200,0,0,63);
- if (sonarinchL1 > 240) stroke(200,255,255,63);
- arc(sx, sy, sonarinchL1 * 2.0, sonarinchL1 * 2.0, (ardheaddraw2 - beamwidth), (ardheaddraw2 + beamwidth));
- }
- if (dataCode1.equals("L") && dataCode2.contains("2")){
- sonarinchL2 = int(indata);
- sx = (500 + ardposx) + (cos(ardheaddraw + 0.6) * 8.0);
- sy = (300 - ardposy) - (sin(ardheaddraw + 0.6) * 8.0);
- sxp = sx + (cos(ardheaddraw + QUARTER_PI) * sonarinchL2);
- syp = sy - (sin(ardheaddraw + QUARTER_PI) * sonarinchL2);
- stroke(200,255,255,63); fill(200,255,255,63);
- line(sx, sy, sxp, syp);
- stroke(200,0,0,63);
- if (sonarinchL2 > 240) stroke(200,255,255,63);
- arc(sx, sy, sonarinchL2 * 2.0, sonarinchL2 * 2.0, ((ardheaddraw2 - QUARTER_PI) - beamwidth), ((ardheaddraw2 - QUARTER_PI) + beamwidth));
- }
- if (dataCode1.equals("R") && dataCode2.contains("1")){
- sonarinchR1 = int(indata);
- sx = (500 + ardposx) + (cos(ardheaddraw - 0.5) * 15.0);
- sy = (300 - ardposy) - (sin(ardheaddraw - 0.5) * 15.0);
- sxp = sx + (cos(ardheaddraw) * sonarinchR1);
- syp = sy - (sin(ardheaddraw) * sonarinchR1);
- stroke(200,255,255,63); fill(200,255,255,63);
- line(sx, sy, sxp, syp);
- stroke(200,0,0,63);
- if (sonarinchR1 > 240) stroke(200,255,255,63);
- arc(sx, sy, sonarinchR1 * 2.0, sonarinchR1 * 2.0, (ardheaddraw2 - beamwidth), (ardheaddraw2 + beamwidth));
- }
- if (dataCode1.equals("R") && dataCode2.contains("2")){
- sonarinchR2 = int(indata);
- sx = (500 + ardposx) + (cos(ardheaddraw - 0.6) * 8.0);
- sy = (300 - ardposy) - (sin(ardheaddraw - 0.6) * 8.0);
- sxp = sx + (cos(ardheaddraw - QUARTER_PI) * sonarinchR2);
- syp = sy - (sin(ardheaddraw - QUARTER_PI) * sonarinchR2);
- stroke(200,255,255,63); fill(200,255,255,63);
- line(sx, sy, sxp, syp);
- stroke(200,0,0,63);
- if (sonarinchR2 > 240) stroke(200,255,255,63);
- arc(sx, sy, sonarinchR2 * 2.0, sonarinchR2 * 2.0, ((ardheaddraw2 + QUARTER_PI) - beamwidth), ((ardheaddraw2 + QUARTER_PI) + beamwidth));
- }
- stroke(200,0,0,127);
- point(sxp,syp);
- if (dataCode1.equals("P") && dataCode2.contains("X")){
- ardposx = indata;
- }
- if (dataCode1.equals("P") && dataCode2.contains("Y")){
- ardposy = indata;
- stroke(200,255,255, 63); fill(200,255,255, 63);
- ellipse(ardposx + 500, -ardposy + 300, 20, 20);
- stroke(0,0,0);
- point(ardposx + 500, -ardposy + 300);
- }
- if (dataCode1.equals("H") && dataCode2.contains("0")){
- ardheading = indata;
- ardheaddraw = indata + HALF_PI;
- ardheaddraw2 = (-indata) - HALF_PI;
- }
- if (dataCode1.equals("H") && dataCode2.contains("1")){
- ardcompass = indata;
- }
- stroke(0,0,0);
- fill(0,0,0);
- }
- //parse com5 GPS
- void parseStringcom5 (String serialString) {
- //sets up an array and splits the gps info by comma
- String items[] = split(serialString,',');
- if(items[0].equals("$GPGGA")) { //looks for the GPGGA info
- getGGA(items);
- }
- if(items[0].equals("$GPRMC")) { //looks for the GPRMC info
- getRMC(items);
- }
- //Convert data for Arduino
- Heading1 = int(-Heading1 * (PI / 180.0) * 1000.0) / 1000.0;//0-360 to 0 - -2PI
- if (Heading1 < -PI) Heading1 = Heading1 + TWO_PI;//0-2PI to -PI - PI
- //begin transmitting data to Arduino
- com4.write("<" + Satellites1 + "S0>");
- com4.write("<" + Heading1 + "H0>");
- //end transmission
- }
- //this function assigns the variables
- //to array elements that have been parsed
- void getGGA(String[] gpsinfo){
- //if (gpsinfo[1].equals("A")){
- Latitude1 = float(gpsinfo[2])/100.0;//DD.MM.MMMM
- Latitude2 = Latitude1 - int(Latitude1);//00.MMMMMM
- Latitude2 = (Latitude2 * 100.0) / 60.0;//00.DDDD
- Latitude1 = int(Latitude1) + Latitude2;//DD.DDDD
- Latitude = nfs(Latitude1, 3,7);
- NorSindicator = gpsinfo[3];
- Longitude1 = float( gpsinfo[4])/100.0;//DDD.MM.MMMM
- Longitude2 = Longitude1 - int(Longitude1);//00.MMMMMM
- Longitude2 = (Longitude2 * 100.0) / 60.0;//00.DDDD
- Longitude1 = int(Longitude1) + Longitude2;//DD.DDDD
- Longitude = nfs(Longitude1, 3,7);
- EorWindicator = gpsinfo[5];
- Lock1 = int(gpsinfo[6]);
- Lock = nfs(Lock1, 1, 0);
- Satellites1 = int(gpsinfo[7]);
- Satellites = nfs(Satellites1, 2, 0);
- Altitude = gpsinfo[9];
- gpsdata = join(gpsinfo,",");
- }
- void getRMC(String[] gpsinfo){
- //if (gpsinfo[1].equals("A")){
- Speed1 = float(gpsinfo[7]);
- Speed = nfs(Speed1, 3,2);
- Heading1 = float( gpsinfo[8]);
- Heading = nfs(Heading1, 3,2);
- gpsdata2 = join(gpsinfo,",");
- }
- //check for keys being pressed, and send them to arduino
- void keyPressed() {
- if (keys[keyCode] == 0){
- com4.write("<" + keyCode + "K1>");
- keys[keyCode] = 1;
- }
- }
- void keyReleased() {
- if (keys[keyCode] == 1){
- com4.write("<" + keyCode + "K0>");
- keys[keyCode] = 0;
- }
- }
1