Skip to content

Commit c44f933

Browse files
Major API Update
1 parent 4993ea3 commit c44f933

File tree

5 files changed

+276
-50
lines changed

5 files changed

+276
-50
lines changed

AVISEngine.py

Lines changed: 123 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,48 +1,98 @@
1-
# @ 2020, Copyright Amirmohammad Zarif
2-
# AVIS Engine
1+
'''
2+
@ 2022, Copyright AVIS Engine
3+
'''
4+
35
import cv2
4-
import os
5-
import io
66
import re
7-
import time
8-
import math
97
import base64
8+
import time
109
import socket
1110
import 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()

Example.py

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,26 @@
1-
# @ 2020, Copyright Amirmohammad Zarif
2-
# Compatible with AVISEngine version 1.0.1 or higher
1+
'''
2+
@ 2022, Copyright AVIS Engine
3+
Example Compatible with AVISEngine version 2.0.1 or higher
4+
'''
35
import AVISEngine
6+
import config
47
import time
58
import cv2
69

710
#Calling the class
8-
car = AVISEngine.car()
11+
car = AVISEngine.Car()
912

1013
#connecting to the server (Simulator)
11-
car.connect("127.0.0.1", 25001)
14+
car.connect(config.SIMULATOR_IP, config.SIMULATOR_PORT)
1215

1316
#Counter variable
1417
counter = 0
1518

1619
debug_mode = False
17-
#sleep for 3 seconds to make sure that client connected to the simulator
20+
21+
#Sleep for 3 seconds to make sure that client connected to the simulator
1822
time.sleep(3)
23+
1924
try:
2025
while(True):
2126
#Counting the loops
@@ -27,12 +32,16 @@
2732

2833
#Set the Steering of the car -10 degree from center
2934
car.setSteering(-10)
35+
36+
#Set the angle between sensor rays to 30 degrees, Use this only if you want to set it from python client
37+
car.setSensorAngle(40)
3038

3139
#Get the data. Need to call it every time getting image and sensor data
3240
car.getData()
3341

3442
#Start getting image and sensor data after 4 loops. for unclear some reason it's really important
3543
if(counter > 4):
44+
3645
#returns a list with three items which the 1st one is Left sensor data, the 2nd one is the Middle Sensor data, and the 3rd is the Right one.
3746
sensors = car.getSensors()
3847
#EX) sensors[0] returns an int for left sensor data in cm
@@ -46,21 +55,14 @@
4655
#Don't print data for better performance
4756
if(debug_mode):
4857
print("Speed : ",carSpeed)
49-
#currently the angle between the sensors is 30 degree TODO : be able to change that from conf.py
5058
print("Left : " + str(sensors[0]) + " | " + "Middle : " + str(sensors[1]) +" | " + "Right : " + str(sensors[2]))
5159

52-
#showing the opencv type image
60+
#Showing the opencv type image
5361
cv2.imshow('frames', image)
54-
#break the loop when q pressed
62+
#Break the loop when q pressed
5563
if cv2.waitKey(10) == ord('q'):
5664
break
5765
time.sleep(0.001)
58-
#A brief sleep to make sure everything
59-
60-
finally:
61-
car.stop()
62-
63-
64-
65-
6666

67+
finally:
68+
car.stop()

README.md

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,34 @@
22
A Python API Implemented for AVIS Engine(Autonomous Vehicles Intelligent simulation Software).
33

44
# Changelog (Simulator)
5+
### - 2.1.0 (-Not Released: Planned for March, 2022)
6+
- Switching to ZMQ
7+
- Configuration file
8+
- Configurable Camera settings (FOV, Position, Mode, Bird-eye view, ...)
9+
- Configurable Post Processing (DOF, Bloom, Color Corrections, ...)
10+
- Semantic mode
11+
- Depth Camera
12+
- Radar
13+
- Pub-sub pattern messaging system
14+
15+
### - 2.0.1
16+
- Major API Update
17+
- Updated Image Encoding
18+
- Compressed TCP Packets
19+
- Added Utils.py
20+
- Added Config.py
21+
- Higher Resolution camera with better performance
22+
- Adjustable Camera Resolution
23+
- Message Compression Algorithm
24+
- Defined <EOF> tag in transfered data from simulator to client
25+
- Adjustable front sensor angle
26+
- Added KMP Search to find <EOF>
27+
28+
### - 2.0.0 Major Update
29+
- Added a New City
30+
- Added Fog
31+
- Improvements
32+
533
### - 1.2.0
634
- Added localization and multilingual support. (English, Persian, Russian, France, German, Chinese, Italian, Spanish, Japanese, Korean, Turkish)
735
- Visual Improvements.

config.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
'''
2+
@ 2022, Copyright AVIS Engine
3+
'''
4+
5+
SIMULATOR_IP = "127.0.0.1"
6+
SIMULATOR_PORT = 25001
7+
8+
CAMERA_RESOLUTION = [720, 360] # [Width, Height]
9+
10+

0 commit comments

Comments
 (0)