1- # @ 2020, Copyright Amirmohammad Zarif
2- # AVIS Engine
1+ '''
2+ @ 2022, Copyright AVIS Engine
3+ '''
4+
35import cv2
4- import os
5- import io
66import re
7- import time
8- import math
97import base64
8+ import time
109import socket
1110import numpy as np
12- from PIL import Image
13- from array import array
11+ import utils
1412
15- #Take in base64 string and return PIL image
16- def stringToImage (base64_string ):
17- imgdata = base64 .b64decode (base64_string )
18- return Image .open (io .BytesIO (imgdata ))
13+ __author__ = "Amirmohammad Zarif"
14+ __email__ = "amirmohammadzarif@avisengine.com"
1915
20- #convert PIL Image to an RGB image( technically a numpy array ) that's compatible with opencv
21- def toRGB (image ):
22- return cv2 .cvtColor (np .array (image ), cv2 .COLOR_BGR2RGB )
2316
24- class car ():
17+ class Car ():
18+ '''
19+ AVIS Engine Main car class
20+
21+ Attributes
22+ ----------
23+
24+ Private:
25+ steering_value
26+ speed_value
27+ sensor_status
28+ image_mode
29+ get_Speed
30+ data_arr
31+ data_str
32+ sock
33+ image
34+ sensors
35+ current_speed
36+ sensor_angle
37+ '''
38+
39+ #Attributes to kind of replicate a Pub-sub pattern messaging to request data
2540 steering_value = 0
2641 speed_value = 0
2742 sensor_status = 1
2843 image_mode = 1
2944 get_Speed = 1
45+ sensor_angle = 30
46+
3047 sock = socket .socket (socket .AF_INET , socket .SOCK_STREAM )
31- data_arr = [speed_value ,steering_value ,image_mode ,sensor_status ,get_Speed ]
32- data_str = "Speed:" + str (data_arr [0 ]) + ",Steering:" + str (data_arr [1 ]) + ",ImageStatus:" + str (data_arr [2 ]) + ",SensorStatus:" + str (data_arr [3 ]) + ",GetSpeed:" + str (data_arr [4 ])
48+
49+ #Data format for request
50+ data_arr = [speed_value , steering_value , image_mode , sensor_status , get_Speed , sensor_angle ]
51+ _data_format = "Speed:{},Steering:{},ImageStatus:{},SensorStatus:{},GetSpeed:{},SensorAngle:{}"
52+ data_str = _data_format .format (data_arr [0 ], data_arr [1 ], data_arr [2 ], data_arr [3 ], data_arr [4 ], data_arr [5 ])
53+
3354 image = None
3455 sensors = None
3556 current_speed = None
57+
3658 def connect (self ,server ,port ):
59+ '''
60+ Connecting to the simulator (server)
61+ '''
3762 try :
3863 self .sock .connect ((server , port ))
3964 self .sock .settimeout (5.0 )
65+
4066 print ("connected to " , server , port )
4167 return True
4268 except :
4369 print ("Failed to connect to " , server , port )
4470 return False
71+
72+ def recvall (self , socket ):
73+ '''
74+ Function to receive all the data chunks
75+ '''
76+ BUFFER_SIZE = 131072
77+ data = ""
78+ while True :
79+ part = socket .recv (BUFFER_SIZE ).decode ("utf-8" )
80+ data += part
81+ # Use KMP search to find the <EOF>, KMPSearch() returns -1 if the pattern was not found
82+ if (utils .KMPSearch ("<EOF>" , data ) > - 1 ):
83+ break
84+
85+ return data
86+
4587 def setSteering (self ,steering ):
88+ '''
89+ Setting the steering of the car
90+
91+ Parameters
92+ ----------
93+ steering : int
94+ Steering value in degree
95+ '''
4696 self .steering_value = steering
4797 self .image_mode = 0
4898 self .sensor_status = 0
@@ -51,27 +101,50 @@ def setSteering(self,steering):
51101 time .sleep (0.01 )
52102
53103 def setSpeed (self ,speed ):
104+ '''
105+ Setting the speed of the car
106+
107+ Parameters
108+ ----------
109+ speed : int
110+ '''
54111 self .speed_value = speed
55112 self .image_mode = 0
56113 self .sensor_status = 0
57114 self .updateData ()
58115 self .sock .sendall (self .data_str .encode ("utf-8" ))
59116 time .sleep (0.01 )
60-
61- def move (self ):
117+
118+ def setSensorAngle (self , angle ):
119+ '''
120+ Setting the angle between each sensor ray
121+
122+ Parameters
123+ ----------
124+ angle : int
125+ In degrees
126+ '''
127+
128+ self .image_mode = 0
129+ self .sensor_status = 0
130+ self .sensor_angle = angle
62131 self .updateData ()
63132 self .sock .sendall (self .data_str .encode ("utf-8" ))
64-
133+
65134 def getData (self ):
135+ '''
136+ Requesting for the data from the simulator
137+ '''
66138 self .image_mode = 1
67139 self .sensor_status = 1
68140 self .updateData ()
69141 self .sock .sendall (self .data_str .encode ("utf-8" ))
70- recive = self .sock .recv (131072 ).decode ("utf-8" )
71- imageTagCheck = re .search ('<image>(.*?)<\/image>' , recive )
72- sensorTagCheck = re .search ('<sensor>(.*?)<\/sensor>' , recive )
73- speedTagCheck = re .search ('<speed>(.*?)<\/speed>' , recive )
74-
142+
143+ receive = self .recvall (self .sock )
144+
145+ imageTagCheck = re .search ('<image>(.*?)<\/image>' , receive )
146+ sensorTagCheck = re .search ('<sensor>(.*?)<\/sensor>' , receive )
147+ speedTagCheck = re .search ('<speed>(.*?)<\/speed>' , receive )
75148
76149 try :
77150 if (imageTagCheck ):
@@ -88,36 +161,52 @@ def getData(self):
88161 self .sensors = sensor_int_arr
89162 else :
90163 self .sensors = [1500 ,1500 ,1500 ]
164+
91165 if (speedTagCheck ):
92166 current_sp = speedTagCheck .group (1 )
93167 self .current_speed = int (current_sp )
94168 else :
95169 self .current_speed = 0
96-
97-
98170 except :
99- pass
100-
171+ print ( "Failed to receive data" )
172+
101173
102174 def getImage (self ):
175+ '''
176+ Returns the image from the camera
177+ '''
103178 return self .image
104179
105180 def getSensors (self ):
181+ '''
182+ Returns the sensor data
183+ A List:
184+ [Left Sensor: int, Middle Sensor: int, Right Sensor: int]
185+ '''
106186 return self .sensors
107187
108188 def getSpeed (self ):
189+ '''
190+ Returns the speed of the car
191+ '''
109192 return self .current_speed
110193
111194 def updateData (self ):
112- data = [self .speed_value ,self .steering_value ,self .image_mode ,self .sensor_status ,self .get_Speed ]
113- self .data_str = "Speed:" + str (data [0 ]) + ",Steering:" + str (data [1 ]) + ",ImageStatus:" + str (data [2 ]) + ",SensorStatus:" + str (data [3 ]) + ",GetSpeed:" + str (data [4 ])
114-
195+ '''
196+ Updating the request data array and data string
197+ '''
198+ data = [self .speed_value ,self .steering_value ,self .image_mode ,self .sensor_status ,self .get_Speed , self .sensor_angle ]
199+ self .data_str = self ._data_format .format (data [0 ], data [1 ], data [2 ], data [3 ], data [4 ], data [5 ])
200+
115201 def stop (self ):
202+ '''
203+ Stoping the car and closing the socket
204+ '''
116205 self .setSpeed (0 )
117206 self .setSteering (0 )
118207 self .sock .sendall ("stop" .encode ("utf-8" ))
119208 self .sock .close ()
120- print ("done " )
209+ print ("Process stopped successfully! " )
121210
122211 def __del__ (self ):
123212 self .stop ()
0 commit comments