1
- """
1
+ '''
2
2
@ 2025, Copyright AVIS Engine
3
- """
3
+ '''
4
4
5
5
import cv2
6
6
import re
7
7
import base64
8
8
import time
9
9
import socket
10
10
import numpy as np
11
- from . import utils
11
+ import utils
12
12
13
13
__author__ = "Amirmohammad Zarif"
14
14
__email__ = "amir@avisengine.com"
15
15
16
16
17
- class Car :
18
- """
17
+ class Car () :
18
+ '''
19
19
AVIS Engine Main Car class
20
-
20
+
21
21
Attributes
22
22
----------
23
23
@@ -34,57 +34,47 @@ class Car:
34
34
sensors
35
35
current_speed
36
36
sensor_angle
37
- """
37
+ '''
38
38
39
- # Attributes to kind of replicate a Pub-sub pattern messaging to request data
39
+ #Attributes to kind of replicate a Pub-sub pattern messaging to request data
40
40
steering_value = 0
41
41
speed_value = 0
42
42
sensor_status = 1
43
43
image_mode = 1
44
44
get_Speed = 1
45
45
sensor_angle = 30
46
-
46
+
47
47
sock = socket .socket (socket .AF_INET , socket .SOCK_STREAM )
48
48
49
- # Data format for request
50
- data_arr = [
51
- speed_value ,
52
- steering_value ,
53
- image_mode ,
54
- sensor_status ,
55
- get_Speed ,
56
- sensor_angle ,
57
- ]
58
- _data_format = (
59
- "Speed:{},Steering:{},ImageStatus:{},SensorStatus:{},GetSpeed:{},SensorAngle:{}"
60
- )
61
- data_str = _data_format .format (
62
- data_arr [0 ], data_arr [1 ], data_arr [2 ], data_arr [3 ], data_arr [4 ], data_arr [5 ]
63
- )
64
-
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
+
65
54
image = None
66
55
sensors = None
67
56
current_speed = None
68
57
69
- def connect (self , server , port ):
70
- """
58
+ def connect (self ,server ,port ):
59
+ '''
71
60
Connecting to the simulator (server)
72
- """
61
+ '''
73
62
try :
74
63
self .sock .connect ((server , port ))
75
64
self .sock .settimeout (5.0 )
76
-
65
+
77
66
print ("connected to " , server , port )
78
67
return True
79
68
except :
80
69
print ("Failed to connect to " , server , port )
81
70
return False
82
71
72
+
83
73
def recvall (self , socket ):
84
- """
74
+ '''
85
75
Function to receive all the data chunks
86
- """
87
- BUFFER_SIZE = 65536 # Increased buffer size for better performance
76
+ '''
77
+ BUFFER_SIZE = 131072 # Increased buffer size for better performance
88
78
data = bytearray () # Use a bytearray for better performance
89
79
90
80
while True :
@@ -93,35 +83,36 @@ def recvall(self, socket):
93
83
94
84
# Use KMP search to find the <EOF>, KMPSearch() returns -1 if the pattern was not found
95
85
# It is 9 times faster than the simple python search
96
- if utils .KMPSearch (b"<EOF>" , data ) > - 1 : # Convert "<EOF>" to bytes
86
+ if utils .KMPSearch (b"<EOF>" , data ) > - 1 : # Convert "<EOF>" to bytes
97
87
break
98
88
99
89
return data .decode ("utf-8" )
100
90
101
- def setSteering (self , steering ):
102
- """
91
+
92
+ def setSteering (self ,steering ):
93
+ '''
103
94
Setting the steering of the car
104
-
95
+
105
96
Parameters
106
97
----------
107
98
steering : int
108
99
Steering value in degree
109
- """
100
+ '''
110
101
self .steering_value = steering
111
102
self .image_mode = 0
112
103
self .sensor_status = 0
113
104
self .updateData ()
114
105
self .sock .sendall (self .data_str .encode ("utf-8" ))
115
106
time .sleep (0.01 )
116
107
117
- def setSpeed (self , speed ):
118
- """
108
+ def setSpeed (self ,speed ):
109
+ '''
119
110
Setting the speed of the car
120
-
111
+
121
112
Parameters
122
113
----------
123
114
speed : int
124
- """
115
+ '''
125
116
self .speed_value = speed
126
117
self .image_mode = 0
127
118
self .sensor_status = 0
@@ -130,107 +121,100 @@ def setSpeed(self, speed):
130
121
time .sleep (0.01 )
131
122
132
123
def setSensorAngle (self , angle ):
133
- """
124
+ '''
134
125
Setting the angle between each sensor ray
135
-
126
+
136
127
Parameters
137
128
----------
138
129
angle : int
139
130
In degrees
140
- """
131
+ '''
141
132
142
133
self .image_mode = 0
143
134
self .sensor_status = 0
144
135
self .sensor_angle = angle
145
136
self .updateData ()
146
137
self .sock .sendall (self .data_str .encode ("utf-8" ))
147
-
138
+
148
139
def getData (self ):
149
- """
140
+ '''
150
141
Requesting for the data from the simulator
151
- """
142
+ '''
152
143
self .image_mode = 1
153
144
self .sensor_status = 1
154
145
self .updateData ()
155
146
self .sock .sendall (self .data_str .encode ("utf-8" ))
156
147
157
148
receive = self .recvall (self .sock )
158
149
159
- imageTagCheck = re .search (r" <image>(.*?)</image>" , receive )
160
- sensorTagCheck = re .search (r" <sensor>(.*?)</sensor>" , receive )
161
- speedTagCheck = re .search (r" <speed>(.*?)</speed>" , receive )
162
-
150
+ imageTagCheck = re .search (' <image>(.*?)<\ /image>' , receive )
151
+ sensorTagCheck = re .search (' <sensor>(.*?)<\ /sensor>' , receive )
152
+ speedTagCheck = re .search (' <speed>(.*?)<\ /speed>' , receive )
153
+
163
154
try :
164
- if imageTagCheck :
155
+ if ( imageTagCheck ) :
165
156
imageData = imageTagCheck .group (1 )
166
157
im_bytes = base64 .b64decode (imageData )
167
- im_arr = np .frombuffer (
168
- im_bytes , dtype = np .uint8
169
- ) # im_arr is one-dim Numpy array
158
+ im_arr = np .frombuffer (im_bytes , dtype = np .uint8 ) # im_arr is one-dim Numpy array
170
159
imageOpenCV = cv2 .imdecode (im_arr , flags = cv2 .IMREAD_COLOR )
171
160
self .image = imageOpenCV
172
-
173
- if sensorTagCheck :
161
+
162
+ if ( sensorTagCheck ) :
174
163
sensorData = sensorTagCheck .group (1 )
175
- sensor_arr = re .findall (r "\d+" , sensorData )
176
- sensor_int_arr = list (map (int , sensor_arr ))
164
+ sensor_arr = re .findall ("\d+" , sensorData )
165
+ sensor_int_arr = list (map (int , sensor_arr ))
177
166
self .sensors = sensor_int_arr
178
167
else :
179
- self .sensors = [1500 , 1500 , 1500 ]
168
+ self .sensors = [1500 ,1500 ,1500 ]
180
169
181
- if speedTagCheck :
170
+ if ( speedTagCheck ) :
182
171
current_sp = speedTagCheck .group (1 )
183
172
self .current_speed = int (current_sp )
184
173
else :
185
174
self .current_speed = 0
186
175
except :
187
176
print ("Failed to receive data" )
188
177
178
+
189
179
def getImage (self ):
190
- """
180
+ '''
191
181
Returns the image from the camera
192
- """
182
+ '''
193
183
return self .image
194
184
195
185
def getSensors (self ):
196
- """
186
+ '''
197
187
Returns the sensor data
198
- A List:
188
+ A List:
199
189
[Left Sensor: int, Middle Sensor: int, Right Sensor: int]
200
- """
190
+ '''
201
191
return self .sensors
202
-
192
+
203
193
def getSpeed (self ):
204
- """
194
+ '''
205
195
Returns the speed of the car
206
- """
196
+ '''
207
197
return self .current_speed
208
-
198
+
209
199
def updateData (self ):
210
- """
200
+ '''
211
201
Updating the request data array and data string
212
- """
213
- data = [
214
- self .speed_value ,
215
- self .steering_value ,
216
- self .image_mode ,
217
- self .sensor_status ,
218
- self .get_Speed ,
219
- self .sensor_angle ,
220
- ]
221
- self .data_str = self ._data_format .format (
222
- data [0 ], data [1 ], data [2 ], data [3 ], data [4 ], data [5 ]
223
- )
224
-
202
+ '''
203
+ data = [self .speed_value ,self .steering_value ,self .image_mode ,self .sensor_status ,self .get_Speed , self .sensor_angle ]
204
+ self .data_str = self ._data_format .format (data [0 ], data [1 ], data [2 ], data [3 ], data [4 ], data [5 ])
205
+
225
206
def stop (self ):
226
- """
207
+ '''
227
208
Stoping the car and closing the socket
228
- """
209
+ '''
229
210
self .setSpeed (0 )
230
211
self .setSteering (0 )
231
212
self .sock .sendall ("stop" .encode ("utf-8" ))
232
213
self .sock .close ()
233
214
print ("Process stopped successfully!" )
234
-
215
+
235
216
def __del__ (self ):
236
217
self .stop ()
218
+
219
+
220
+
0 commit comments