diff --git a/docs/readthedocs/chapters/usage/software.rst b/docs/readthedocs/chapters/usage/software.rst index b71c7fc8..b6f5b8eb 100644 --- a/docs/readthedocs/chapters/usage/software.rst +++ b/docs/readthedocs/chapters/usage/software.rst @@ -79,16 +79,70 @@ Client side Advanced Folder Transfer ^^^^^^^^^^^^^^^^^^^^^^^^ -*Creator: Jerry Kong +*Creator: Jerry Kong* To meet our need of a neat and organized data structure, this script is created. It has the capability to transfer the entire folder to another remote desktop, no matter it is on a Windows System or Unix system. -The script rests in PiCar/src/Logging +The script rests in ``PiCar/src/Logging`` To use the script, first setup the ip addresses like in the basic version, change the root variable to the root folder name. Place the script at the same level as the root folder. Start the server script and then start the client script. The folder would then be transferred. A better protocol could be implemented, since the protocol now being used is not really efficient though fulfill the need of our experiment for now. +WIFI Router setting +^^^^^^^^^^^^^^^^^^^ + +*Creator: Jerry Kong* + +*This section is dedicated to users who are not familiar with WIFI network setting, TCP protocol and wireless connection* + +To establish communication between two machine we need to know their address. Moreover, to provide a consistent and save network experience, a machine would have many ports to receive connections with different forms, +thus we also need to agree on the port that two machine establish the connection on. However, depending on different internet environment and different ways of connection (wifi or ethernet), the IP address would also vary. +Read through this section, you would get a sense of how this astonishingly complicated system works and hopefully learn how to cope with "Connection fails" error when you are using the script I wrote in the repo or any kind of +Internet application. + +IP +### + +IP's full name is Internet Protocol. It's a scheme that specifies how computers find each other in the pool of Internet. The rules behind it is complicated, but the most important thing is that it is a identification +for modern computer wired to Internet and is universally used as the synonym of IP address. + +IPv4? IPv6? +########### + +As a protocal, IP would have different versions, the latest version is version 6 and thus called IPv6. While IPv6 is stronger and has a larger pool of Internet, the older version IPv4 is not obsoleted. +The logic behind the two protocals are the same, hence we would now stick with IPv4, since it has a more concise format. (XXX.XX.XX.XXX) + +WIFI vs ethernet +################ + +You must be familiar with this topic. WIFI is more convenient while wired connection (ethernet) offer steadiness and low latency. However, it is important to note that a computer connected to wifi does not have an IP, or at least, an acknowledged IP. +Wifi or the router serves as a broadcaster and spread the connection from the ethernet to multiple machines, but they have the same IP address. The router can identify each machine by the IP address it assigns to the machine, but the machine can't use +that address as the identification on the internet. Conclusively, machines under the same WIFI build up a small Internet where these machines can identify each other by the address they are assigned, but once outside WIFI network they are no longer acknowledged. + +See +`Setup static IP address for RaspberryPi `_ +, so a machine would be assigned the same IP address when connected to the WIFI. + +TCP +### + +TCP, transmission Control Protocol, is a higher level protocol that enables data sending via the connection established by IP. Socket, a method based on TCP is prevailing on data transfer. + +Port and Port forwarding +######################## + +With the knowledge about address in mind we could start the connection once we have the right port. It is easy to do so if both machines are on Internet or under the same WIFI, since they can identify with each other. Just pick up an empty port and they are good to go. +However, we do want to establish connection between two machines even if one is on WIFI and the other is on Internet. To do so, these smart people invented port forwarding. With port forwarding, a client can find the address of the router and use the port that is forwarded to connect with the machine. + +For example, the address of the router is 172.10.10.111, and a machine under the WIFI is assigned static IP 192.168.1.188. The routher and the machine agree on that the connection to the port 30000 of the routher would be forwarded to the port 6000 of the machine and vice versa. +Thus a laptop could setup a connection with 172.10.10.111 on port 30000 to connect the port 6000 on machine with static IP 192.168.1.188. + +See +`How to setup port forwarding `_ + + + Sensors(Lidar,IMU) reading and writing -------------------------------------- @@ -210,11 +264,27 @@ The script is based on delta timing method. A constant value of 0.0007 is subtra Precision defines the minimum time that the script goes to check the diffrence between the last time and current time and consequently defines within what time difference that measures of LiDar and IMU occur simultaneously. -Using -i command line input, we could run the script in endless mode (i.e. the duration would be set to 1000 seconds, we could stop the program by using KeyboardInterrupt(Ctrl + C), the pictures and logging data would be save up until the stopping point) **A great part of the codes are from Josh Jin's sensor/camera reading code** +Version Beta (Magnetic reading added to IMU) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +*Creator : Jerry Kong* + +*The code could be found in PiCar/src/pi/IMU_Lidar, the socket_server_client.py file is a integrated and important part of this data logging script, to learn more about socket folder sending, take a look at* ` socket based file sending `_ + +Endless mode is implemented. User could stop the experiment with KeyboardInterrupt, the logging file and camera file would still be saved + +Using -i command line input, we could run the script in endless mode (i.e. the duration would be set to 1000 seconds, we could stop the program by using KeyboardInterrupt(Ctrl + C)) + +Logging file sending module is integarted into the logging script. After the multiprocessing finished (loggind and filming), the script would start a raw socket server and a client on another computer could use the client side script to receive the logging file. + +The script could either be called from the terminal or from other script by calling the funtion getSensorAndCamera. + +'-s' command line argument and save parameter for getSensorAndCamera is implemented so that users can decide whether they want the logging file to be saved locally. +For installation and usage see the previous section Data Analysis ------------- diff --git a/src/logging/socket_folder_client.py b/src/logging/socket_folder_client.py index 49672fe3..07bca7d0 100644 --- a/src/logging/socket_folder_client.py +++ b/src/logging/socket_folder_client.py @@ -1,19 +1,25 @@ # client.py + +# for picar lab students use command "python3 socket_folder_client.py 172.16.10.208 31418" import os import sys import socket # Import socket module import time s = socket.socket() # Create a socket object -host = 'localhost' # Get local machine name -port = 60001 # Reserve a port for your service. +host = sys.argv[1] # Get local machine name +port = int(sys.argv[2]) # Reserve a port for your service. s.connect((host, port)) data=s.recv(1024) +#print(len(data)) +if len(data)!=1024: + sup = s.recv(1024-len(data)) + data = bytearray(data)+sup[0:] l=int.from_bytes(data[0:2],byteorder='big',signed='true') flds = data[2:2+l].decode('ascii') folders = flds.split("!") for folder in folders: - if folder!="" and " " not in folder: + if folder!="": os.mkdir(folder) file = "" @@ -22,6 +28,13 @@ get = s.recv(1024) if not get: break + if len(get)!=1024: + sup = s.recv(1024-len(get)) + while len(get)==0: + sup = s.recv(1024-len(get)) + #print(str(len(sup))+"sup") + get = bytearray(get)+sup[0:] + #print(len(get)) ll = int.from_bytes(get[0:2],byteorder='big',signed='true') if ll>=0 and file!="": f.write(get[2:2+ll]) @@ -39,4 +52,3 @@ s.close() print('connection closed') - diff --git a/src/logging/socket_folder_server.py b/src/logging/socket_folder_server.py index 5bd15b1f..6fe411be 100644 --- a/src/logging/socket_folder_server.py +++ b/src/logging/socket_folder_server.py @@ -1,47 +1,49 @@ import os +import sys import socket # Import socket module -port = 60001 # Reserve a port for your service. -s = socket.socket() # Create a socket object -host = "localhost" # Get local machine name -s.bind((host, port)) # Bind to the port -s.listen(5) # Now wait for client connection. -root = "rt" -print ("begin") -folders = [] -files = [] - -for dirname, dirnames, filenames in os.walk(root): - # print path to all subdirectories first. - for subdirname in dirnames: - folders.append(os.path.join(dirname, subdirname)) - # print path to all filenames. - for filename in filenames: - files.append(os.path.join(dirname, filename)) - - -conn, addr = s.accept() # Establish connection with client. -print ('Got connection from', addr) -#transfer folder -folderstream = root+"!"+"".join([folder+"!" for folder in folders]) -fl = len(folderstream) -conn.send(bytearray((fl).to_bytes(2,byteorder='big',signed='true'))+folderstream.encode('ascii')[0:]+bytearray(1022-fl)[0:]) - - -for file in files: - length = len(file) - conn.send((-length).to_bytes(2,byteorder='big',signed='true')) - conn.send(file.encode('ascii')) - conn.send(bytes(1022-length)) - f = open(file,'rb') - l = f.read(1022) - while (l): - k = len(l) - conn.send(k.to_bytes(2,byteorder='big',signed='true')) - conn.send(l) - if 1022-k != 0: - conn.send(bytes(1022-k)) - l = f.read(1022) #alter this to control data sending rate - f.close() - -conn.close() \ No newline at end of file +#pi tarzan 192.168.1.121 + +def send(host,port,root): + # Reserve a port for your service. + s = socket.socket() # Create a socket object + # Get local machine name + s.bind((host, port)) # Bind to the port + s.listen(5) # Now wait for client connection. + print ("begin") + folders = [] + files = [] + + for dirname, dirnames, filenames in os.walk(root): + # print path to all subdirectories first. + for subdirname in dirnames: + folders.append(os.path.join(dirname, subdirname)) + # print path to all filenames. + for filename in filenames: + files.append(os.path.join(dirname, filename)) + + + conn, addr = s.accept() # Establish connection with client. + print ('Got connection from', addr) + #transfer folder + folderstream = root+"!"+"".join([folder+"!" for folder in folders]) + fl = len(folderstream) + conn.send(bytearray((fl).to_bytes(2,byteorder='big',signed='true'))+folderstream.encode('ascii')[0:]+bytearray(1022-fl)[0:]) + + + for file in files: + length = len(file) + conn.send(bytearray((-length).to_bytes(2,byteorder='big',signed='true'))+file.encode('ascii')[0:]+bytes(1022-length)[0:]) + f = open(file,'rb') + l = f.read(1022) + while (l): + k = len(l) + conn.send(bytearray(k.to_bytes(2,byteorder='big',signed='true'))+l[0:]+bytes(1022-k)[0:]) + l = f.read(1022) #alter this to control data sending rate + f.close() + + conn.close() + +if __name__=='__main__': + send(sys.argv[1],int(sys.argv[2]),sys.argv[3]) + diff --git a/src/pi/IMU_Lidar/Lidar_IMU_read_beta.py b/src/pi/IMU_Lidar/Lidar_IMU_read_beta.py new file mode 100644 index 00000000..9fe73a77 --- /dev/null +++ b/src/pi/IMU_Lidar/Lidar_IMU_read_beta.py @@ -0,0 +1,269 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -* +#No extra package required to run the script +#However, be sure you read the documentation on http://picar.readthedocs.io/en/latest/chapters/usage/software.html#data-logging +import os +import serial +import time +import datetime +import sys +import csv +import threading +import picamera +import argparse +import signal +from socket_folder_server import send +from multiprocessing import Process,Event +from IMU_SETUP import lib + + + +def pre_exec(): + # To ignore CTRL+C signal in the new process + signal.signal(signal.SIGINT, signal.SIG_IGN) + + +#see document for available scales + +def setIMUScale(aScl=2,gScl=245,mScl=4): + global imu + lib.lsm9ds1_setAccelScale(imu,aScl) + lib.lsm9ds1_setGyroScale(imu,gScl) + lib.lsm9ds1_setMagScale(imu,mScl) + +#see document for available tranmission rate + +def setIMUodr(aRate=6,gRate=6,mRate=7): + global imu + lib.lsm9ds1_setAccelODR(imu,aRate) + lib.lsm9ds1_setGyroODR(imu,gRate) + lib.lsm9ds1_setMagODR(imu,mRate) + +#get IMU data +def getIMU(): + global imu + lib.lsm9ds1_readAccel(imu) + lib.lsm9ds1_readGyro(imu) + lib.lsm9ds1_readMag(imu) + ax = lib.lsm9ds1_getAccelX(imu) + ay = lib.lsm9ds1_getAccelY(imu) + az = lib.lsm9ds1_getAccelZ(imu) + cax = lib.lsm9ds1_calcAccel(imu, ax) + cay = lib.lsm9ds1_calcAccel(imu, ay) + caz = lib.lsm9ds1_calcAccel(imu, az) + gx = lib.lsm9ds1_getGyroX(imu) + gy = lib.lsm9ds1_getGyroY(imu) + gz = lib.lsm9ds1_getGyroZ(imu) + cgx = lib.lsm9ds1_calcGyro(imu, gx) + cgy = lib.lsm9ds1_calcGyro(imu, gy) + cgz = lib.lsm9ds1_calcGyro(imu, gz) + mx = lib.lsm9ds1_getMagX(imu) + my = lib.lsm9ds1_getMagY(imu) + mz = lib.lsm9ds1_getMagZ(imu) + cmx = lib.lsm9ds1_calcMag(imu,mx) + cmy = lib.lsm9ds1_calcMag(imu,my) + cmz = lib.lsm9ds1_calcMag(imu,mz) + return (cax,cay,caz,cgx,cgy,cgz,cmx,cmy,cmz) + + + +#get TFmini Lidar data +def getLidar(): + #TFmini data + recv = ser.read(9) + ser.reset_input_buffer() + + if recv[0] == 0x59 and recv[1] == 0x59: + distance = recv[2] + recv[3] * 256 + ser.reset_input_buffer() + return distance + else: + ser.reset_input_buffer() + return "UP" + + +#a timer wrapped inside a python generator to take picture +def filenames(alive,duration,cameraFreq,beginTime): + startTime = time.time() + lastTime = time.time() + current = time.time() + while current-startTimecameraFreq: + name = datetime.datetime.now() + #name = time.time() + name = beginTime+'/camera/'+str(name)+'.jpg' + lastTime = time.time() + yield name + + +def capture(alive,duration,cameraFreq,beginTime): + pre_exec() + camera = picamera.PiCamera(resolution=(480,480), framerate=40) + camera.capture_sequence(filenames(alive,duration,cameraFreq,beginTime), use_video_port=True) + + +#the function which calls getIMU and getLidar +def getData(alive,duration,precision,imuRate,lidarRate,datafile,rowList): + pre_exec() + global imu + startTime = time.time() + lastTimeLidar = time.time() + lastTimeIMU = lastTimeLidar + lastTime = lastTimeLidar + current = time.time() + while current - startTime < duration and not alive.is_set(): + #define the precision, i.e. the gap between two consecutive IMU or LiDar read + if current-lastTime>precision: + lastTime = current + if current-lastTimeIMU>imuRate and lib.lsm9ds1_accelAvailable(imu) > 0 and current-lastTimeLidar>lidarRate and ser.in_waiting > 8: + lastTimeIMU = time.time() + IMUdata = getIMU() + Lidardata = getLidar() + currentTime = str(datetime.datetime.fromtimestamp(lastTimeIMU)) + #currentTime = str(lastTimeIMU) + lastTimeLidar = lastTimeIMU + rowList.append([currentTime,Lidardata,IMUdata[0],IMUdata[1],IMUdata[2],IMUdata[3],IMUdata[4],IMUdata[5],IMUdata[6],IMUdata[7],IMUdata[8]]) + elif current-lastTimeIMU>imuRate and lib.lsm9ds1_accelAvailable(imu) > 0: + lastTimeIMU = time.time() + IMUdata = getIMU() + currentTime = str(datetime.datetime.fromtimestamp(lastTimeIMU)) + #currentTime = str(lastTimeIMU) + rowList.append([currentTime,"NA",IMUdata[0],IMUdata[1],IMUdata[2],IMUdata[3],IMUdata[4],IMUdata[5],IMUdata[6],IMUdata[7],IMUdata[8]]) + elif current-lastTimeLidar>lidarRate and ser.in_waiting > 8: + lastTimeLidar = time.time() + Lidardata = getLidar() + currentTime = str(datetime.datetime.fromtimestamp(lastTimeLidar)) + #currentTime = str(lastTimeLidar) + rowList.append([currentTime,Lidardata,"NA","NA","NA","NA","NA","NA","NA","NA","NA"]) + + current = time.time() + + print("start writing data") + with open(datafile,"w") as csvfile: + spamwriter = csv.writer(csvfile, delimiter=',', quoting=csv.QUOTE_MINIMAL) + for row in rowList: + spamwriter.writerow(row) + + +#connect with IMU +imu = lib.lsm9ds1_create() +lib.lsm9ds1_begin(imu) +ser = serial.Serial("/dev/ttyS0", 115200) #serial port for Lidar + + +def getSensorAndCamera(host='192.168.1.121',port=6000,save=False,duration=5,endless=False,trAccRate=6,trGyroRate=6,trMagRate=7,accScale=2,gyroScale=245,magScale=4,cameraFreq=5,imuRate=50,lidarRate=50,precision=0.001): + beginTime = str(datetime.datetime.now()) + os.makedirs(beginTime+"/camera") + datafile = beginTime+'/Lidar_IMU_Data.csv' + rowList=[] + if endless: + duration = 1000 + lidarRate = float(1)/lidarRate - 0.0007 + imuRate = float(1)/imuRate - 0.0007 + cameraFreq = float(1)/cameraFreq + setIMUScale(accScale,gyroScale,magScale) + setIMUodr(trAccRate,trGyroRate,trMagRate) + if lib.lsm9ds1_begin(imu) == 0: + print("Failed to communicate with LSM9DS1.") + quit() + lib.lsm9ds1_calibrate(imu) + try: + if ser.is_open == False: + ser.open() + print(time.time()) + alive = Event() + #multicore process + pic = Process(target = capture,args=(alive,duration,cameraFreq,beginTime,)) + sensor = Process(target = getData,args=(alive,duration,precision,imuRate,lidarRate,datafile,rowList,)) + + pic.start() + sensor.start() + pic.join() + sensor.join() + #subprocess.Popen("python3 socket_folder_server.py localhost 60004 \""+beginTime+"\"",shell=True) + except KeyboardInterrupt: # Ctrl+C + if ser != None: + ser.close() + alive.set() + pic.join() + sensor.join() + print(time.time()) + send(host,port,beginTime) + if not save: + os.system("rm -r \""+beginTime+"\"") + + +if __name__ == '__main__': + beginTime = str(datetime.datetime.now()) + parser = argparse.ArgumentParser(description = 'PiCar log file generator', formatter_class = argparse.RawTextHelpFormatter, conflict_handler = 'resolve') + parser.add_argument("--ip",help="Ip of this raspberry pi",default="192.168.1.121") + parser.add_argument("--po",help = "port for connection",type = int,default=6000) + parser.add_argument("-i","--t", help = "endless mode", action='store_const',const=1000 , default =5 ) + parser.add_argument("--t",help = "determine the duration that the test runs", type = int, default = 5) + parser.add_argument("--sa",help = "set accelerometer ODR, available values(default = 6): \n 1 = 10 Hz 4 = 238 Hz \n 2 = 50 Hz 5 = 476 Hz \n 3 = 119 Hz 6 = 952 Hz", type = int, choices=[1,2,3,4,5,6], default = 6) + parser.add_argument("--sg",help = "set gyro ODR, available values(default = 6): \n 1 = 14.9 4 = 238 \n 2 = 59.5 5 = 476 \n 3 = 119 6 = 952", type = int, choices = [1,2,3,4,5,6],default = 6) + parser.add_argument("--sm",help = "set mag ODR, available values(default = 7): \n 0 = 0.625 Hz 4 = 10 Hz \n 1 = 1.25 Hz 5 = 20 Hz \n 2 = 2.5 Hz 6 = 40 Hz \n 3 = 5 Hz 7 = 80 Hz", type = int, choices = [0,1,2,3,4,5,6,7], default = 7) + parser.add_argument("--a",help = "set acc scale, available values(default = 2): 2, 4, 8, 16 (g)", type = int, choices = [2,4,8,16], default = 2) + parser.add_argument("--g",help = "set gyro scale, available values(default = 245): 245, 500, 2000", type = int, choices = [245,500,2000], default = 245) + parser.add_argument("--m", help = "set mag scale, available values(default = 4) : 4, 8, 12, 16", type = int, choices = [4,8,12,16],default=4) + parser.add_argument("--c",help = "set camera filming rate(Hz)", type = int, default = 5) + parser.add_argument("--ri",help = "set imu reading rate(Hz)", type = int, default = 50) + parser.add_argument("--rl", help = "set LiDar reading rate(Hz)", type = int, default = 50) + parser.add_argument("--p",help = "set the precision of the timing", type = float, default = 0.001) + parser.add_argument("-s",help = "save the log locally after test", action="store_true", default=False) + re = parser.parse_args() + + os.makedirs(beginTime+"/camera") + + + + + + datafile = beginTime+'/Lidar_IMU_Data.csv' + + rowList = [] + host = re.ip + port = re.po + duration = re.t + trAccRate = re.sa + trGyroRate = re.sg + trMagRate = re.sm + accScale = re.a + gyroScale = re.g + magScale = re.m + lidarRate = float(1)/(re.rl)-0.0007 # minus 0.0007 to compensate for the call of time.time() + imuRate = 1/float(re.ri)-0.0007 + precision = re.p + cameraFreq = 1/float(re.c) + save = re.s + setIMUScale(accScale,gyroScale,magScale) + setIMUodr(trAccRate,trGyroRate,trMagRate) + if lib.lsm9ds1_begin(imu) == 0: + print("Failed to communicate with LSM9DS1.") + quit() + lib.lsm9ds1_calibrate(imu) + try: + if ser.is_open == False: + ser.open() + print(time.time()) + alive = Event() + #multicore process + pic = Process(target = capture,args=(alive,duration,cameraFreq,beginTime,)) + sensor = Process(target = getData,args=(alive,duration,precision,imuRate,lidarRate,datafile,rowList,)) + + pic.start() + sensor.start() + pic.join() + sensor.join() + #subprocess.Popen("python3 socket_folder_server.py localhost 60004 \""+beginTime+"\"",shell=True) + except KeyboardInterrupt: # Ctrl+C + if ser != None: + ser.close() + alive.set() + pic.join() + sensor.join() + print(time.time()) + send(host,port,beginTime) + if not save: + os.system("rm -r \""+beginTime+"\"") diff --git a/src/pi/IMU_Lidar/Lidar_IMU_read_optimize_delta.py b/src/pi/IMU_Lidar/Lidar_IMU_read_optimize_delta.py index a14b9a85..ed922583 100644 --- a/src/pi/IMU_Lidar/Lidar_IMU_read_optimize_delta.py +++ b/src/pi/IMU_Lidar/Lidar_IMU_read_optimize_delta.py @@ -12,17 +12,21 @@ import picamera import argparse import signal -from multiprocessing import Process,Value +from socket_folder_server import send +from multiprocessing import Process,Event from IMU_SETUP import lib beginTime = str(datetime.datetime.now()) + sys.version[0] == '3' #declare for python 3 parser = argparse.ArgumentParser(description = 'PiCar log file generator', formatter_class = argparse.RawTextHelpFormatter, conflict_handler = 'resolve') +parser.add_argument("--ip",help="Ip of this raspberry pi",default="192.168.1.121") +parser.add_argument("--po",help = "port for connection",type = int,default=60000) parser.add_argument("-i","--t", help = "endless mode", action='store_const',const=1000 , default =5 ) parser.add_argument("--t",help = "determine the duration that the test runs", type = int, default = 5) parser.add_argument("--sa",help = "set accelerometer ODR, available values(default = 6): \n 1 = 10 Hz 4 = 238 Hz \n 2 = 50 Hz 5 = 476 Hz \n 3 = 119 Hz 6 = 952 Hz", type = int, choices=[1,2,3,4,5,6], default = 6) @@ -46,6 +50,8 @@ datafile = beginTime+'/Lidar_IMU_Data.csv' rowList = [] +host = re.ip +port = re.po duration = re.t trAccRate = re.sa trGyroRate = re.sg @@ -59,6 +65,11 @@ cameraFreq = 1/float(re.c) +def pre_exec(): + # To ignore CTRL+C signal in the new process + signal.signal(signal.SIGINT, signal.SIG_IGN) + + #see document for available scales def setIMUScale(aScl=2,gScl=245,mScl=4): @@ -112,33 +123,36 @@ def getLidar(): #a timer wrapped inside a python generator to take picture -def filenames(): +def filenames(alive): startTime = time.time() lastTime = time.time() current = time.time() - while current-startTimecameraFreq: name = datetime.datetime.now() + #name = time.time() name = beginTime+'/camera/'+str(name)+'.jpg' lastTime = time.time() yield name -def capture(): +def capture(alive): + pre_exec() camera = picamera.PiCamera(resolution=(480,480), framerate=40) - camera.capture_sequence(filenames(), use_video_port=True) + camera.capture_sequence(filenames(alive), use_video_port=True) #the function which calls getIMU and getLidar def getData(alive): + pre_exec() global imu startTime = time.time() lastTimeLidar = time.time() lastTimeIMU = lastTimeLidar lastTime = lastTimeLidar current = time.time() - while current - startTime < duration and alive.value: + while current - startTime < duration and not alive.is_set(): #define the precision, i.e. the gap between two consecutive IMU or LiDar read if current-lastTime>precision: lastTime = current @@ -147,17 +161,20 @@ def getData(alive): IMUdata = getIMU() Lidardata = getLidar() currentTime = str(datetime.datetime.fromtimestamp(lastTimeIMU)) + #currentTime = str(lastTimeIMU) lastTimeLidar = lastTimeIMU rowList.append([currentTime,Lidardata,IMUdata[0],IMUdata[1],IMUdata[2],IMUdata[3],IMUdata[4],IMUdata[5]]) elif current-lastTimeIMU>imuRate and lib.lsm9ds1_accelAvailable(imu) > 0: lastTimeIMU = time.time() IMUdata = getIMU() currentTime = str(datetime.datetime.fromtimestamp(lastTimeIMU)) + #currentTime = str(lastTimeIMU) rowList.append([currentTime,"NA",IMUdata[0],IMUdata[1],IMUdata[2],IMUdata[3],IMUdata[4],IMUdata[5]]) elif current-lastTimeLidar>lidarRate and ser.in_waiting > 8: lastTimeLidar = time.time() Lidardata = getLidar() currentTime = str(datetime.datetime.fromtimestamp(lastTimeLidar)) + #currentTime = str(lastTimeLidar) rowList.append([currentTime,Lidardata,"NA","NA","NA","NA","NA","NA"]) current = time.time() @@ -185,20 +202,22 @@ def getData(alive): if ser.is_open == False: ser.open() print(time.time()) - alive = Value('b',True) + alive = Event() #multicore process - pic = Process(target = capture) - sensor = Process(target = getData, args=(alive,)) + pic = Process(target = capture,args=(alive,)) + sensor = Process(target = getData,args=(alive,)) pic.start() sensor.start() pic.join() sensor.join() - - print(time.time()) + #subprocess.Popen("python3 socket_folder_server.py localhost 60004 \""+beginTime+"\"",shell=True) except KeyboardInterrupt: # Ctrl+C if ser != None: ser.close() - pic.terminate() - alive.value = False - sys.exit() + alive.set() + pic.join() + sensor.join() + print(time.time()) + send(host,port,beginTime) + \ No newline at end of file diff --git a/src/pi/IMU_Lidar/socket_folder_server.py b/src/pi/IMU_Lidar/socket_folder_server.py new file mode 100644 index 00000000..6fe411be --- /dev/null +++ b/src/pi/IMU_Lidar/socket_folder_server.py @@ -0,0 +1,49 @@ +import os +import sys +import socket # Import socket module + +#pi tarzan 192.168.1.121 + +def send(host,port,root): + # Reserve a port for your service. + s = socket.socket() # Create a socket object + # Get local machine name + s.bind((host, port)) # Bind to the port + s.listen(5) # Now wait for client connection. + print ("begin") + folders = [] + files = [] + + for dirname, dirnames, filenames in os.walk(root): + # print path to all subdirectories first. + for subdirname in dirnames: + folders.append(os.path.join(dirname, subdirname)) + # print path to all filenames. + for filename in filenames: + files.append(os.path.join(dirname, filename)) + + + conn, addr = s.accept() # Establish connection with client. + print ('Got connection from', addr) + #transfer folder + folderstream = root+"!"+"".join([folder+"!" for folder in folders]) + fl = len(folderstream) + conn.send(bytearray((fl).to_bytes(2,byteorder='big',signed='true'))+folderstream.encode('ascii')[0:]+bytearray(1022-fl)[0:]) + + + for file in files: + length = len(file) + conn.send(bytearray((-length).to_bytes(2,byteorder='big',signed='true'))+file.encode('ascii')[0:]+bytes(1022-length)[0:]) + f = open(file,'rb') + l = f.read(1022) + while (l): + k = len(l) + conn.send(bytearray(k.to_bytes(2,byteorder='big',signed='true'))+l[0:]+bytes(1022-k)[0:]) + l = f.read(1022) #alter this to control data sending rate + f.close() + + conn.close() + +if __name__=='__main__': + send(sys.argv[1],int(sys.argv[2]),sys.argv[3]) +