Kevin KatheRounak ChowdhuryKush Patel
Created December 15, 2021

ME461 Floor Mapping Robot Project

This is an obstacle detecting robot that can map itself and its surroundings in LabVIEW in real-time.

IntermediateWork in progress15 hours16
ME461 Floor Mapping Robot Project

Things used in this project

Hardware components

LAUNCHXL-F28379D C2000 Delfino LaunchPad
Texas Instruments LAUNCHXL-F28379D C2000 Delfino LaunchPad
×1
Raspberry Pi Orange Pi Lite
×1
IR Range Sensor
Digilent IR Range Sensor
×3
Ultrasonic Sensor - HC-SR04 (Generic)
Ultrasonic Sensor - HC-SR04 (Generic)
×2
Geared DC Motor, 12 V
Geared DC Motor, 12 V
×2
SparkFun RedBot Sensor - Wheel Encoder
SparkFun RedBot Sensor - Wheel Encoder
×2
Li-Polymer Battery, 150mAh
Li-Polymer Battery, 150mAh
×1

Software apps and online services

Code Composer Studio
Texas Instruments Code Composer Studio
LabVIEW Community Edition
LabVIEW Community Edition

Hand tools and fabrication machines

Multitool, Screwdriver
Multitool, Screwdriver
Soldering iron (generic)
Soldering iron (generic)
TAZ 6
LulzBot TAZ 6

Story

Read more

Custom parts and enclosures

ME461 Robot Upgrades

Flat Mount This design was an extension of a given cad file. I added IR sensor mounts and Ultrasonic cutouts while improving structural rigidity and creating ease of access points to reach certain wires and mounts. Caster Standoff To keep the robot level with the ground, I created a caster wheel standoff to help stabilize the robot and create a stronger mount for the caster itself.

Orange Pi Lite Slim Case Standard

Used to encase the Orange Pi and create a safe way to mount to the robot.

Schematics

Sensor Overview Video

Diagram of Path of Robot

Diagram of Obstacle Avoidance Procedure

Code

LabView VIs

C/C++
This is a Zip file containing all pertinent LabVIEW files needed to display robot and obstacle data.
No preview (download only).

Obstacle Avoidance and PI Communication Code

C/C++
ZIP File Containing all Necessary Code for Avoiding Obstacles and Communicating with the Orange PI from the Red Board
No preview (download only).

Orange Pi TCPIP code

C Header File
This code transmits 9 values over wifi to labiew from the orange pi.
#include "TCPIPServerUARTto28x.h"

union float_char
{
    float val[9]; //changed from 2 to 9 to involve 9 values in the array 
    char bytes[36]; //changed from 8 bytes to 36 to include the 9 floats instead of 2 
};


#define SERFILE "/dev/ttyS2"
#define SERIALBUFFSIZE 1024
float cx; //position of the center(in percentage)
float cy; //position of the center(in percentage)
union float_char to_send;
union float_char received;


/*
 * setup_serial()
 *   sets the serial port up at 115200 baud
 */
int setup_serial()
{
    sd_setup(SERFILE); //starts non-blocking
    sd_ioflush();
}



int TCPIPtransmissionerror = 0;		// Initialize transmission error count
int TCPIPbeginnewdata = 0;
int TCPIPdatasize = 0;

int EchoString = 0;
int numTXChars = 0;

#define INBUFFSIZE (2048)
#define OUTBUFFSIZE (INBUFFSIZE + 2)
char TCPIPMessageArray[INBUFFSIZE + 2]; 

char inbuf[INBUFFSIZE+2]; //changed frmo +2 to +5
unsigned char outbuf[OUTBUFFSIZE];
int accepted_skt;

/*  
 * gs_killapp()
 *   ends application safely
 *
 */
void gs_killapp(int s)
{
  printf("\nTerminating\n");
  gs_quit = 1;
  gs_exit = 1;
  close(gs_coms_skt);
  return;
}
 


/*
 * init_server()
 *   Starts up listening socket
 */
int init_server()
{
  int on = 1;

  // Communications sockets,
  // tcp:
  gs_coms_skt = tcpsock();  
  
  if (setsockopt(gs_coms_skt, SOL_SOCKET,SO_REUSEADDR, (char*)&on, sizeof(on)) < 0) {
	 printf("Error Reusing Socket\n");
  }
  sockbind(gs_coms_skt, gs_port_coms);
  socklisten(gs_coms_skt);
  printf("Listening on port %d\n.",gs_port_coms);
  sock_set_blocking(gs_coms_skt);
}

void tcp_signal_handler_IO (int status)
{
  int i,j;

  int numrecChars = 0;

	
  for (i=0;i<INBUFFSIZE/2;i++) {
    inbuf[i] = '\0';
  }

  numrecChars = read(accepted_skt, inbuf, INBUFFSIZE/2); 
  if (numrecChars > 0)  {
	for (i=0;i<numrecChars;i++) {
		if (!TCPIPbeginnewdata) {// Only true if have not yet begun a message
			if ('*' == (unsigned char)inbuf[i]) {// Check for start char
				TCPIPdatasize = 0;		// amount of data collected in message set to 0
				TCPIPbeginnewdata = 1;		// flag to indicate we are collecting a message
			}
		} else {	// Filling data
			// Dont go too large... limit message to 256 chars  this can be made larger if you change inbuf size
			if ((TCPIPdatasize < INBUFFSIZE) && ((unsigned char)inbuf[i] != '#')) {	
				TCPIPMessageArray[TCPIPdatasize] = inbuf[i];				
				TCPIPdatasize++;
			} else {  // too much data or 255 char received
				if ((unsigned char)inbuf[i] != 255) {// check if end character recvd
					// Not received
					TCPIPtransmissionerror++;
					printf("TXerrors = %d\n",TCPIPtransmissionerror);
				} 
				// Whether or not message terminated correctly, send data to other tasks
				TCPIPMessageArray[TCPIPdatasize] = '\0'; 	// Null terminate the string
				TCPIPdatasize++;  // increment by one so that the Null is copied to shared memory
				printf("Received String:%s\n",TCPIPMessageArray);
				EchoString = 1;
				//Do something with this UART   TCPIPMessageArray[j];
						
				TCPIPbeginnewdata = 0;	// Reset the flag
				TCPIPdatasize = 0;	// Reset the number of chars collected
			}	
		}
	}
  } else {
  printf("numrecChars = %d\n",numrecChars);
  printf("\nReseting\n");
  gs_quit = 1;
  close(gs_coms_skt);

  } 
	     
  // call this kill when kill string is sent
  //      gs_killapp(0);
  

  return;
}




/*
 * run_server()
 *   This function runs until the server quits and it:
 *
 *   1. accepts incoming TCP connections
 *   2. reads from ready sockets and writes incoming messages
 *      to the serial port / controls devices
 *   3. reads from serial port and prints
 */
int run_server()
{
	sigset_t sigio_set; 
	struct sigaction saio;           /* definition of signal action */
	static struct sockaddr_in addr;  
	int i;

	// Accept new connection
	accepted_skt = connaccept(gs_coms_skt, &addr);
	// We don't wanna block either source
	sock_set_nonblocking(accepted_skt);
	int flags = fcntl(accepted_skt, F_GETFL,0);
	fcntl (accepted_skt,F_SETFL,flags|FASYNC);
	fcntl(accepted_skt, F_SETOWN, getpid());

	sigemptyset(&sigio_set);
	sigaddset(&sigio_set,SIGIO); 
	saio.sa_handler = tcp_signal_handler_IO;
	saio.sa_flags = SA_SIGINFO;
	sigemptyset(&saio.sa_mask);
	saio.sa_mask = sigio_set;
	if (sigaction(SIGIO,&saio,NULL)) {
		printf("Error in sigaction()\n");
		return 1;
	}

	if (accepted_skt>0) {
		printf("Connection accepted from %d.%d.%d.%d\n",
		(addr.sin_addr.s_addr&0x000000ff),      
		(addr.sin_addr.s_addr&0x0000ff00)>>8,
		(addr.sin_addr.s_addr&0x00ff0000)>>16,
		(addr.sin_addr.s_addr&0xff000000)>>24);
	}
	printf(".\n");
	while (!gs_quit) {
		sched_yield();
			
		//Here get data from serial port and then print and then send
		if (EchoString == 1) {	
			sscanf( TCPIPMessageArray, "%f %f %f %f %f %f %f %f %f", &to_send.val[0], &to_send.val[1], &to_send.val[2], &to_send.val[3], &to_send.val[4], &to_send.val[5], &to_send.val[6], &to_send.val[7], &to_send.val[8]); //changed to include all 5 values, replaces the next two lines basically
			//to_send.val[0] = keypoints[max_index].pt.x;
            		//to_send.val[1] = keypoints[max_index].pt.y;

			printf("Send String:%.3f %.3f %.3f %.3f %.3f %.3f %.3f %.3f %.3f\n", to_send.val[0],to_send.val[1],to_send.val[2],to_send.val[3],to_send.val[4],to_send.val[5],to_send.val[6],to_send.val[7],to_send.val[8]);
			//changed above line to include 13 values 
			
			
            		sd_write("*");
            		sd_write("*");
            		sd_writen(to_send.bytes,36); //changed from 8 bytes, as each float is 4 bytes and there is 9 floats
            		usleep(50000);
            		sd_write("!");
            		sd_write("!");
           		sd_readn(received.bytes,36); //changed from 8 bytes, as each float is 4 bytes and there is 9 floats
		        printf("RECEIVEvalue1 = %.3f value2 = %.3f value3 = %.3f value4 = %.3f value5 = %.3f value6 = %.3f value7 = %.3f value8 = %.3f value9 = %.3f\n ",received.val[0],received.val[1],received.val[2],received.val[3],received.val[4],received.val[5],received.val[6],received.val[7],received.val[8]);
			//changed above line to include 9 values 
        		numTXChars = sprintf(((char *) outbuf),"%.3f %.3f %.3f %.3f %.3f %.3f %.3f %.3f %.3f\r\n",received.val[0],received.val[1],received.val[2],received.val[3],received.val[4],received.val[5],received.val[6],received.val[7],received.val[8]);
			//changed above line to include 9 values
			write(accepted_skt, outbuf, numTXChars);

			EchoString = 0;
		}
	}
}




/*
 * main()
 *   process command line input
 */
int main (int argc, char **argv)
{
	int index = 0;
	int firsttime = 1;

	if (argc ==2) {
		printf("using port %s\n",argv[1]);
		gs_port_coms = atoi(argv[1]);
	}

//init UART

	to_send.val[0] = 0.1234;
	to_send.val[1] = 0.4567;
	to_send.val[2] = 0.5123;//added in 
	to_send.val[3] = 0.6192;//added in
	to_send.val[5] = 0.7182;//added in 
	to_send.val[6] = 0.7182;//added in 
	to_send.val[7] = 0.7182;//added in 
	to_send.val[8] = 0.7182;//added in 

	printf("Initializing serial port driver %s...\n", "/dev/ttyS2");
	setup_serial();
	printf("...OK\n");

        sd_set_blocking();
        printf(".\n");
        sd_ioflush();

	printf("Setting signal handler...\n");
	signal(SIGKILL, gs_killapp);
	signal(SIGINT, gs_killapp);
	printf("...OK\n");
	while (!gs_exit) {
		gs_quit = 0;

		if (!firsttime) {
			printf("Waiting 2 Seconds to make sure socket data is cleaned from the network.\n");
			sleep(2);
		}

		printf("Initializing listening connection...\n");
		init_server();
		firsttime = 0;
		printf("...OK\n");

		printf("Accepting connections...\n");
		run_server();
	}

}

Credits

Kevin Kathe
1 project • 0 followers
Rounak Chowdhury
1 project • 0 followers
Kush Patel
1 project • 0 followers

Comments