Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Febupdates #4

Open
wants to merge 22 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 18 additions & 21 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,23 +1,20 @@
FROM python:2.7


RUN apt-get update && \
apt-get install -y \
build-essential \
git \
libxerces-c-dev

RUN mkdir -p /opt
RUN (cd /opt; git clone https://github.com/radiganm/sumo.git)
RUN (cd /opt/sumo; ./configure)
RUN (cd /opt/sumo; make)
RUN (cd /opt/sumo; make install)

ENV SUMO_HOME /opt/sumo
# First cache dependencies
ADD ./setup.py /app/setup.py
RUN python /app/setup.py install
# Add sources
FROM starofall/crowdnav

ADD ./ /app/

# WORKDIR /app

# COPY . /app
RUN pip install flask

COPY ./start.sh /app

# WORKDIR /app

EXPOSE 5000

WORKDIR /app
CMD ["python","/app/forever.py"]

RUN chmod 777 ./start.sh

CMD ["bash", "start.sh"]
8 changes: 4 additions & 4 deletions app/Boot.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@
from app.routing.CustomRouter import CustomRouter
from app.network.Network import Network
from app.simulation.Simulation import Simulation
from streaming import RTXForword
from app.streaming import RTXForword
from colorama import Fore
from sumo import SUMOConnector, SUMODependency
import Config
from app.sumo import SUMOConnector, SUMODependency
from app import Config
import traci, sys, os
import thread
#import thread
import time


Expand Down
Empty file added app/HTTPServer/__init__.py
Empty file.
60 changes: 60 additions & 0 deletions app/HTTPServer/endpoints.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
from flask import Flask, jsonify, request
import json


def get_monitor():
file_path = "./monitor_data.json"

try:
with open(file_path, 'r') as json_file:
data = json.load(json_file)
return data

except FileNotFoundError:
raise FileNotFoundError("Monitor data not found")

except Exception as e:
raise e


# Construct the path to the knobs.json file, assuming it's two directories back
json_file_path = './knobs.json'

# Open the JSON file in read mode ('r')
with open(json_file_path, 'r') as json_file:
# Use json.load() to read data from the file
adaptation_options_data = json.load(json_file)

# Now 'data' contains the contents of the JSON file as a Python dictionary
print(adaptation_options_data)




def getexecute():
try:
# Get the JSON data from the request body
request_data = request.get_json()

# Check if the required adaptation fields are present in the request data
required_fields = ["routeRandomSigma", "explorationPercentage", "maxSpeedAndLengthFactor",
"averageEdgeDurationFactor", "freshnessUpdateFactor", "freshnessCutOffValue",
"reRouteEveryTicks"]
if not all(field in request_data for field in required_fields):
return jsonify({"error": "Missing required fields in the adaptation request"}), 400

# Implement your adaptation logic here based on the received data
# For demonstration, we'll print the received data
print('Received adaptation data: {request_data}')

# Return a response indicating the success of the adaptation
return jsonify({"message": "Adaptation executed successfully"})

except Exception as e:
# Handle exceptions and return an error response
return jsonify({"error": str(e)}), 500

def getAdaptationOptions():
return adaptation_options_data


113 changes: 113 additions & 0 deletions app/HTTPServer/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
from flask import Flask, jsonify
from flask.views import MethodView
import json
from endpoints import get_monitor

app = Flask(__name__)

knobs_path = '../../knobs.json'


def read_knobs():
"""Read the knobs.json file."""
try:
with open(knobs_path, 'r') as file:
knobs_data = json.load(file)
return knobs_data
except FileNotFoundError:
return None


def write_knobs(data):
"""Write data to the knobs.json file."""
with open(knobs_path, 'w') as file:
json.dump(data, file, indent=2)


class MonitorAPI(MethodView):
def get(self):
try:
file_path = "app/HTTPServer/monitor_data.json"
with open(file_path, "r") as json_file:
data = json.load(json_file)
return jsonify(data)
except FileNotFoundError:
return jsonify({'error': 'monitor_data.json not found'}), 404


app.add_url_rule('/monitor', view_func=MonitorAPI.as_view('monitor'))


@app.route('/execute', methods=['PUT'])
def execute_adaptation():
data = get_execute()
return jsonify(data)


class MonitorSchemaAPI(MethodView):
def get(self):
schema = {
'vehicle_count': 'number',
'avg_trip_duration': 'number',
'total_trips': 'number',
'avg_trip_overhead': 'number'
}
return jsonify(schema)


app.add_url_rule('/monitor_schema', view_func=MonitorSchemaAPI.as_view('monitor_schema'))


class AdaptationOptionsSchemaAPI(MethodView):
def get(self):
schema = {
'type': 'object',
'properties': {
'routeRandomSigma': {
'type': 'number',
'description': 'The randomization sigma of edge weights'
},
'explorationPercentage': {
'type': 'number',
'description': 'The percentage of routes used for exploration'
},
'maxSpeedAndLengthFactor': {
'type': 'integer',
'description': 'How much the length/speed influences the routing'
},
'averageEdgeDurationFactor': {
'type': 'integer',
'description': 'How much the average edge factor influences the routing'
},
'freshnessUpdateFactor': {
'type': 'integer',
'description': 'How much the freshness update factor influences the routing'
},
'freshnessCutOffValue': {
'type': 'integer',
'description': 'If data is older than this, it is not considered in the algorithm'
},
'reRouteEveryTicks': {
'type': 'integer',
'description': 'Check for a new route every x times after the car starts'
},
# Add more properties as needed
},
'required': [
'routeRandomSigma',
'explorationPercentage',
'maxSpeedAndLengthFactor',
'averageEdgeDurationFactor',
'freshnessUpdateFactor',
'freshnessCutOffValue',
'reRouteEveryTicks'
],
}
return jsonify(schema)


app.add_url_rule('/adaptation_options_schema', view_func=AdaptationOptionsSchemaAPI.as_view('adaptation_options_schema'))


if __name__ == '__main__':
app.run(host='0.0.0.0')
14 changes: 14 additions & 0 deletions app/HTTPServer/monitor_data.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"step":1,
"EdgeID": 2,
"EdgeDensity":{
"edge1": 10,
"edge2": 8,
"edge3": 15
},
"totalCarCounter":2,
"carIndexCounter": 1,
"totalTrips": 1,
"totalTripAverage": 4,
"totalTripOverheadAverage": 44
}
11 changes: 11 additions & 0 deletions app/HTTPServer/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
In order to run the HTTP server:

pip install fastapi
pip install "uvicorn[standard]"
python -m uvicorn main:app --reload


after building the docker image:

docker run -p 3000:5000 -it --link kafka:kafka <image-name>
"then access the port 3000"
49 changes: 49 additions & 0 deletions app/Strategy/strategy.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import traci
import csv
from statistics import mean

##need to implement this onto upisas

class CrowdNavAdaptationStrategy:
def __init__(self, rerouting_threshold=0.4):
self.rerouting_threshold = rerouting_threshold
self.edge_density = {}

def monitor(self):
#this should be retrived from the endpoints
for edge_id in traci.edge.getIDList():
vehicle_ids = traci.edge.getLastStepVehicleIDs(edge_id)
density = len(vehicle_ids)
self.edge_density[edge_id] = density

def analyze(self):
overloaded_streets = []
for edge_id, density in self.edge_density.items():
mean_density = mean(density)
if mean_density > self.rerouting_threshold:
overloaded_streets.append(edge_id)
return overloaded_streets

def plan(self, overloaded_streets):
avoid_streets_signal = []
for _ in range(traci.simulation.getDeltaT()):
signal_value = 0 if traci.simulation.getCurrentEdgeID() in overloaded_streets else 1
avoid_streets_signal.append(signal_value)
return avoid_streets_signal

def execute(self, avoid_streets_signal):
if 0 in avoid_streets_signal:
print("Sending signal to avoid overloaded streets!")
with open('signal.target', 'w') as signal_file:
signal_writer = csv.writer(signal_file, dialect='excel')
signal_writer.writerow(avoid_streets_signal)

def update_knowledge_base(self):
# You can update the knowledge base based on the feedback from the simulation.
# This might involve adjusting thresholds, exploring different rerouting strategies, or updating other parameters.
pass


# Example usage
strategy = CrowdNavAdaptationStrategy()
strategy.run_strategy()
Loading