Browse Source

Update v1.3

master
Evangelos Oulis 5 years ago
parent
commit
46669cae83
  1. BIN
      Photos/screenshot_web_ui.png
  2. 58
      autonomousCar/autonomousCar.ino
  3. 2
      gatewayNode/parking.py
  4. 53
      project.adoc
  5. 90
      project.html
  6. BIN
      serverNode/__pycache__/serv.cpython-37.pyc
  7. 67
      serverNode/serv.py
  8. 35
      webInterface/parking.html

BIN
Photos/screenshot_web_ui.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 159 KiB

After

Width:  |  Height:  |  Size: 108 KiB

58
autonomousCar/autonomousCar.ino

@ -127,37 +127,6 @@ void serialFlush(){
} }
} }
/*
* Stepper Function for Servo.
* 1st Step: straight
* 2nd Step: left
* 3rd Step: straight
* 4th Step: right
*/
void next_step()
{
if(pos == 1)
{ //Servo move to right
turnServo(90, 30);
pos = 2;
}
else if(pos ==2)
{ //Servo move to center
turnServo(30, 90);
pos = 3;
}
else if(pos == 3)
{ //Servo move to left
turnServo(90, 150);
pos = 4;
}
else if(pos == 4)
{ //Servo move to center
turnServo(150, 90);
pos = 1;
}
}
/* /*
* Distance meter via Ultrasonic * Distance meter via Ultrasonic
*/ */
@ -303,9 +272,6 @@ int Serial_Input()
while (number <= 0) { while (number <= 0) {
// convert the incoming byte to a char and add it to the string: // convert the incoming byte to a char and add it to the string:
number = Serial.parseInt(); number = Serial.parseInt();
//Serial.print("Value:");
//Serial.println(number);
// clear the string for new input:
serialFlush(); serialFlush();
} }
// if you get a newline, print the string, then the string's value: // if you get a newline, print the string, then the string's value:
@ -317,28 +283,6 @@ int Serial_Input()
void loop() { void loop() {
// Calculating the distance // Calculating the distance
distance= getDistance(); distance= getDistance();
park(Serial_Input());
// Prints the distance on the Serial Monitor
//Serial.print("Distance: ");
// Serial.println(distance);
// Read serial input:
park(Serial_Input());
//delay(800);
// if (distance <15) {
// // Change direction to motors
// turn(225);
// } else if (distance <13){
// turn(200);
// } else {
// // Change direction to motors
// turn(MAX_WHEEL_SPEED);
// }
// if (distance < 6){
// motor_stop();
// // Set Ultrasonic to next step
// next_step();
// // Move car
// moveCar();
// }
// delay(100);
} }

2
gatewayNode/parking.py

@ -65,7 +65,7 @@ if json_data != "" and json_data != None:
# If parking status changed from previous status # If parking status changed from previous status
# server would informed about this change. # server would informed about this change.
data = """{"no":""" + parkingCode + ""","status":""" + parkingStatus + """, "cookie": \"""" + cookie + """\"}""" data = """{"no":""" + parkingCode + ""","status":""" + parkingStatus + """, "cookie": \"""" + cookie + """\"}"""
r = s.post(url = API_ENDPOINT, data = data) r = requests.post(url = API_ENDPOINT, data = data)
# IO : node prints to output the current # IO : node prints to output the current
if parkingStatus == "0": if parkingStatus == "0":

53
project.adoc

@ -156,6 +156,15 @@ ttyACM0 που βρίσκεται στο directory (/dev/ στα linux) και
} }
---- ----
Μετά της αυθεντικοποίηση του από τον Server τότε λαμβάνει ένα μύνημα το οποίο περιέχει το Session ID το οποίο χρησιμοποιεί
για την μετέπειτα επικοινωνία με αυτόν. Η απάντηση του αιτήματος αυθεντικοποίησης έχει την παρκάτω μορφή.
[source, JSON]
----
{
"cookie": "8yhuxQL0iCid++BPZFXPM959EclBhDmvvrZrqt+yv1s="
}
----
==== Προγραμματισμός Κόμβου ==== Προγραμματισμός Κόμβου
Ο επικοινωνία και ο προγραμματισμός του κόμβου αυτού, που είναι βασισμένος σε ένα Raspberry Pi 1, έγινε με σύνδεση (ssh) Ο επικοινωνία και ο προγραμματισμός του κόμβου αυτού, που είναι βασισμένος σε ένα Raspberry Pi 1, έγινε με σύνδεση (ssh)
@ -359,13 +368,11 @@ image::Photos/screenshot_web_ui.png[1000,800]
==== Υλικά Κόμβου ==== Υλικά Κόμβου
* 1 x Arduino Uno * 1 x Arduino Uno
* 1 x Servo Motor * 1 x Servo Motor
* 1 x Motor Driver * 1 x Motor Driver (Shield 1.1 - L2981)
* 4 x Moter για τους 4 τροχούς * 4 x Moter για τους 4 τροχούς
* 1 x Ultrasonic * 1 x Ultrasonic
* 1 x 9V Battery * 1 x USB Power from Raspberry PI
* 1 x 4,8V Battery
* 1 x Car * 1 x Car
* 1 x Raspberry Pi
==== Υλοποίηση Microcontroller on Car ==== Υλοποίηση Microcontroller on Car
Ο motor driver, το Servo motor καθώς και ο Ultrasonic αισθητήρας κουμπώνουν στον μικροελεγκτή Arduino Uno που χρησιμοποιούμε, Ο motor driver, το Servo motor καθώς και ο Ultrasonic αισθητήρας κουμπώνουν στον μικροελεγκτή Arduino Uno που χρησιμοποιούμε,
@ -374,6 +381,16 @@ image::Photos/screenshot_web_ui.png[1000,800]
Μόλις λάβει την πληροφορία από το Rasperry, υπολογίζουμε με το υπόλοιπο & το πηλίκο της θέσης του parking με το 2, την γραμμή και την θέση που το όχημα πρέπει να παρκάρει. Μόλις λάβει την πληροφορία από το Rasperry, υπολογίζουμε με το υπόλοιπο & το πηλίκο της θέσης του parking με το 2, την γραμμή και την θέση που το όχημα πρέπει να παρκάρει.
Στην συνέχεια , μόλις το όχημα έχει φτάσει μπροστά από την θέση που πρέπει να παρκάρει , με τις μετρήσεις του ultrasonic ελέγχει το πόσο μπροστά ή πίσω θα πάει το όχημα. Στην συνέχεια , μόλις το όχημα έχει φτάσει μπροστά από την θέση που πρέπει να παρκάρει , με τις μετρήσεις του ultrasonic ελέγχει το πόσο μπροστά ή πίσω θα πάει το όχημα.
[source, C]
----
row = (parkingNo / 2);
side = (parkingNo % 2);
if (side == 0) {
row = row - 1;
}
----
==== Προγραμματισμός Microcontroller on Car ==== Προγραμματισμός Microcontroller on Car
O προγραμματισμός του Arduino έγινε με την ίδια λογική όπως έγινε και ο προγραμματισμός του Arduino παραπάνω. O προγραμματισμός του Arduino έγινε με την ίδια λογική όπως έγινε και ο προγραμματισμός του Arduino παραπάνω.
@ -389,12 +406,36 @@ image::Photos/diagram.png[1000,800]
=== Gateway Κόμβος (2~ο~ Μέρος) === Gateway Κόμβος (2~ο~ Μέρος)
Ο Gateway κόμβος του αυτόνομου οχήματος που θα έρθει στην θέση να παρκάρει μόνο του στο parking (ΙοΤ), είναι υπεύθυνος ==== Υλικά Κόμβου
* 1 x Raspberry Pi 1
* 1 x TP-Link WiFi Adapter
* 1 x Powerbank Power
Ο Gateway κόμβος του αυτόνομου οχήματος που θα έρθει στην θέση να παρκάρει μόνο του στο parking, είναι υπεύθυνος
για την διασύνδεση του οχήματος με το διαδίκτυο. Γι' αυτό το λόγο το process που σχεδιάσαμε να τρέχει σε αυτό το σημείο για την διασύνδεση του οχήματος με το διαδίκτυο. Γι' αυτό το λόγο το process που σχεδιάσαμε να τρέχει σε αυτό το σημείο
είναι υπεύθυνο για την αναζήτηση της πληροφορίας ποια είναι η πρώτη ελεύθερη για να παρκάρει το όχημα και στη συνέχεια είναι υπεύθυνο για την αναζήτηση της πληροφορίας, ποια είναι η πρώτη ελεύθερη για να παρκάρει το όχημα και στη συνέχεια
να αποστέλει τον αριθμό της θέσης στον μικροελεγκτή Arduino ο οποίος είναι υπεύθυνος να πάρει αυτή την τιμή και να κατευθύνει να αποστέλει τον αριθμό της θέσης στον μικροελεγκτή Arduino ο οποίος είναι υπεύθυνος να πάρει αυτή την τιμή και να κατευθύνει
το όχημα. το όχημα.
==== Υλοποίηση Gateway on Car
Ο gateway κόμβος ξεκινά μια HTTP σύνδεση με τον κετντρικό Server, ζητώντας μέσω υπηρεσίας REST API το 1~ο~ διαθέσιμο parking.
Αφού διαβάσει την απάντησή του τότε την απόστέλει σε μορφή String στο Arduino μέσω σειριακής επικοινωνίας στο arduino.
==== Προγραμματιμός Gateway on Car
Το process που εκτελεί αυτή την επικοινωνία μεταξύ του κεντρικου Server και το Arduino στο όχημα είναι προγραμματισμένο σε γλώσσα
προγραμματισμού Python.
== Προβλήματα που αντιμετωπίσαμε
* Δεν καταφέραμε να κάνουμε Deploy στο swarmlab τον κεντρικό Server μας έτσι ώστε να έχουμε
via Internet επικοινωνία.
* Δεν καταφέραμε να τελειοποιήσουμε το αυτόνομο παρκάριμα, και την ενορχύστρωσή του με το υπόλοιπο σύστημα. Το πρόβλημα που
αντιμετωπίσαμε συγκεκριμένα ήταν ο έλεγχος των δεδομένων που από το raspberry στο Arduino και το καθαρισμό του buffer στο
Arduino. Αυτό συνεπώς δεν μας επέτρεπε στο Arduino να διαβάσουμε από την σειριακή τον ακέραιο αριθμό (θέση parking) που έστελνε
το raspberry.
.Reminder .Reminder
[NOTE] [NOTE]

90
project.html

File diff suppressed because one or more lines are too long

BIN
serverNode/__pycache__/serv.cpython-37.pyc

Binary file not shown.

67
serverNode/serv.py

@ -20,6 +20,9 @@ CORS(app)
# Session list # Session list
sessions = [] sessions = []
# Chart values
chart = []
# creating an API object # creating an API object
api = Api(app) api = Api(app)
@ -43,6 +46,10 @@ class mySqlConnect:
@property @property
def cursor(self): def cursor(self):
return self.cur return self.cur
@property
def connection(self):
return self.con
# ================================== # ==================================
# Define our functions. # Define our functions.
@ -91,6 +98,32 @@ def isAuthenticated(data):
except KeyError as e: except KeyError as e:
return False return False
# For the chart Data.
def updateChart():
parks = getParkings()
all_parks = len(parks)
full = 0
for p in parks:
if p['status'] == False:
full+=1
j = 1
if len(chart) < 16 :
chart.append(full)
print (chart)
elif len(chart) == 16:
for i in chart:
chart[j] = i
j+=1
if j == 16:
break
chart[0] = full
return True
# ================================================================== # ==================================================================
# making a class for a particular resource # making a class for a particular resource
# the get, post methods correspond to get and post requests # the get, post methods correspond to get and post requests
@ -104,7 +137,7 @@ class Parking(Resource):
try: try:
parks = getParkings() parks = getParkings()
except (mysql.connector.errors.DatabaseError, mysql.connector.errors.InterfaceError) as e: except (mysql.connector.errors.DatabaseError, mysql.connector.errors.InterfaceError) as e:
mydb.reconnect(attempts=1, delay=0) print ("An error")
return parks, 200 return parks, 200
@ -146,23 +179,29 @@ class ParkingStatus(Resource):
thereIs = False thereIs = False
toUpdate = False toUpdate = False
mysql = mySqlConnect()
myCursor = mysql.cur
try: try:
mysql = mySqlConnect()
myCursor = mysql.cur
con = mysql.con
if not thereIs: if not thereIs:
# Make a new insert entry for a new Parking Code. # Make a new insert entry for a new Parking Code.
values = (int(data['no']), int(data['status'])) values = (int(data['no']), int(data['status']))
myCursor.execute("INSERT INTO PARKING (PARKING_CODE, PARKING_STATUS) VALUES (%s, %s)", values) myCursor.execute("INSERT INTO PARKING (PARKING_CODE, PARKING_STATUS) VALUES (%s, %s)", values)
mydb.commit() con.commit()
parks = getParkings() parks = getParkings()
updateChart()
elif toUpdate: elif toUpdate:
# Make an Update status for Parking Code that availability changed. # Make an Update status for Parking Code that availability changed.
values = (int(data['status']), int(data['no'])) values = (int(data['status']), int(data['no']))
myCursor.execute("UPDATE PARKING SET PARKING_STATUS=%s WHERE PARKING_CODE=%s", values) myCursor.execute("UPDATE PARKING SET PARKING_STATUS=%s WHERE PARKING_CODE=%s", values)
mydb.commit() con.commit()
parks = getParkings() parks = getParkings()
updateChart()
except (mysql.connector.errors.DatabaseError, mysql.connector.errors.InterfaceError) as e: except (mysql.connector.errors.DatabaseError, mysql.connector.errors.InterfaceError) as e:
mydb.reconnect(attempts=1, delay=0) print ("An error")
return currentParking, 201 return currentParking, 201
else: else:
@ -190,13 +229,27 @@ class Authenticate(Resource):
else: else:
return "Error authentication", 403 return "Error authentication", 403
except (mysql.connector.errors.DatabaseError, mysql.connector.errors.InterfaceError) as e: except (mysql.connector.errors.DatabaseError, mysql.connector.errors.InterfaceError) as e:
mydb.reconnect(attempts=1, delay=0) print ("An error")
# Chart
class Chart(Resource):
def get(self):
result = dict()
j = 1
for i in chart:
result[j] = i
j += 1
print (result)
return result, 200
# ================================================================== # ==================================================================
# matches the defined resources to their corresponding urls to REST APIs # matches the defined resources to their corresponding urls to REST APIs
api.add_resource(Parking, '/') api.add_resource(Parking, '/')
api.add_resource(ParkingStatus, '/parkingStatus') api.add_resource(ParkingStatus, '/parkingStatus')
api.add_resource(Authenticate, '/authenticate') api.add_resource(Authenticate, '/authenticate')
api.add_resource(Chart, '/chart')
# ================================================================== # ==================================================================
# ===========================MAIN CLASS============================= # ===========================MAIN CLASS=============================

35
webInterface/parking.html

@ -21,6 +21,7 @@ $(document).ready(function(){
alert(server_protocol + "://" + server_ip + " " + server_port + ". Started!!!") alert(server_protocol + "://" + server_ip + " " + server_port + ". Started!!!")
$("#msg").empty(); $("#msg").empty();
if (server_ip !== "" && server_ip !== null && server_port !== "" && server_port !== null && server_protocol !== "" && server_protocol != null) { if (server_ip !== "" && server_ip !== null && server_port !== "" && server_port !== null && server_protocol !== "" && server_protocol != null) {
all_parks = 0;
$("#msg").html("<font color='red'>ok!</font>"); $("#msg").html("<font color='red'>ok!</font>");
$("#approve").prop("disabled", true); $("#approve").prop("disabled", true);
@ -66,6 +67,8 @@ $(document).ready(function(){
row++; row++;
pos = "r"; pos = "r";
} }
all_parks = all_parks + 1;
}); });
}, },
error: function(jqXHR, testStatus, errorThrown) { error: function(jqXHR, testStatus, errorThrown) {
@ -73,6 +76,34 @@ $(document).ready(function(){
timeout: 120000, timeout: 120000,
}); });
jQuery.ajax({
url: server_protocol + "://" + server_ip + ":" + server_port + "/chart",
type: "GET",
contentType: "application/json; charset=utf-8",
success: function(resultData) {
min = 0;
max = all_parks;
chart = "<img src='http://chart.apis.google.com/chart?cht=lc&chs=400x300&chxt=x,x,y,y&chxp=1,50|3,50&chxr=2," + min + "," + max + "|0,0,30&chds=" + min + "," + max + "&chxl=1:|Time|3:|" + "Ελεύθερες Θέσεις" + "&chd=t:"
$.each(resultData, function(key, val) {
console.log("Parking No " + val.no + " -> " + val.status);
if (key > 1) {
chart += "," + val;
} else {
chart += val;
}
});
chart += "'>";
$("div#tab3").html(chart);
},
error: function(jqXHR, testStatus, errorThrown) {
},
timeout: 120000,
});
setInterval(function () { setInterval(function () {
jQuery.ajax({ jQuery.ajax({
url: server_protocol + "://" + server_ip + ":" + server_port + "/", url: server_protocol + "://" + server_ip + ":" + server_port + "/",
@ -132,6 +163,10 @@ $(document).ready(function(){
</table> </table>
</form> </form>
<h3>Διάγραμμα Χώρου Στάθμευσης</h3>
<div id="tab3">
</div>
<h3>Parking Diagram</h3> <h3>Parking Diagram</h3>
<table width="100%" id="tab2"> <table width="100%" id="tab2">
<!--<tr> <!--<tr>

Loading…
Cancel
Save