SUMO - How to control a vehicle's speed via Traci along a given route/trajectory through an intersection - python

I need to set a vehicles speed in each time step by using acceleration values in a network consisting of only one intersection with four connected double lanes (see image). Therefore I have been using the setSpeed command, but have encountered problems. Within the Sumo-GUI the shown speed in the vehicle's parameters show the set speed value and also getSpeed delivers the wanted speed. Nevertheless by calculating the actual velocity by using the driven distances between single time steps (calculated via the vehicle's position) divided by the time step different values are achieved on the lanes. The speed difference is also recognizable within the simulation visualization. As soon as the intersection gets reached the velocity seems correct. The speedMode had been set to zero and the speed limits of the lanes are set to 100 so that can't be the problem. Any help would be highly appreciated. I have tested SUMO 1.1.0 and 1.2.0. In the following the mentioned intersection, an example code in which the vehicle should drive constantly 5 m/s (acceleration = 0) and it's output is shown. As can be seen is the actual velocity as long as driving on the lanes around 3.8 and gets 5 m/s while crossing the intersection. The followed route just goes from left to right.
CODE:
from sumolib import checkBinary
import sys
import traci
step_length = 0.5
traci.start([checkBinary('sumo-gui'), '-c', "Config.sumocfg", '--step-length', str(step_length)])
start_vel = 5
helper_var = 0
vehID = 'car1'
traci.simulationStep()
traci.vehicle.setSpeedMode(vehID, 0)
traci.vehicle.setLaneChangeMode(vehID, 0)
traci.vehicle.setSpeed(vehID, start_vel)
traci.simulationStep()
while traci.simulation.getMinExpectedNumber():
acceleration = 0
newSpeed = traci.vehicle.getSpeed(vehID) + step_length * acceleration
print("Wanted new speed: ", newSpeed)
traci.vehicle.setSpeed(vehID, newSpeed)
traci.simulationStep()
print("Apparently new speed: ", traci.vehicle.getSpeed(vehID))
if helper_var != 0:
print("Actual new speed: ", abs((helper_var - traci.vehicle.getPosition(vehID)[0])/step_length))
helper_var = traci.vehicle.getPosition(vehID)[0]
else:
helper_var = traci.vehicle.getPosition(vehID)[0]
print('---------------------------------------------')
traci.close()
sys.stdout.flush()
PART OF THE OUTPUT BEFORE AND AFTER CROSSING THE JUNCTION:
Wanted new speed: 5.0
Apparently new speed: 5.0
Actual new speed: 3.8000000000000007
---------------------------------------------
Wanted new speed: 5.0
Apparently new speed: 5.0
Actual new speed: 3.799999999999997
---------------------------------------------
Wanted new speed: 5.0
Apparently new speed: 5.0
Actual new speed: 3.8000000000000043
---------------------------------------------
Wanted new speed: 5.0
Apparently new speed: 5.0
Actual new speed: 3.847999999999997
---------------------------------------------
Wanted new speed: 5.0
Apparently new speed: 5.0
Actual new speed: 5.0
---------------------------------------------
Wanted new speed: 5.0
Apparently new speed: 5.0
Actual new speed: 5.0
---------------------------------------------
Wanted new speed: 5.0
Apparently new speed: 5.0
Actual new speed: 5.000000000000002
---------------------------------------------
Wanted new speed: 5.0
Apparently new speed: 5.0
Actual new speed: 4.999999999999998
---------------------------------------------
Wanted new speed: 5.0
Apparently new speed: 5.0
Actual new speed: 5.0
---------------------------------------------
Wanted new speed: 5.0
Apparently new speed: 5.0
Actual new speed: 4.664
---------------------------------------------
Wanted new speed: 5.0
Apparently new speed: 5.0
Actual new speed: 3.8000000000000007
---------------------------------------------
Wanted new speed: 5.0
Apparently new speed: 5.0
Actual new speed: 3.799999999999997
---------------------------------------------
Wanted new speed: 5.0
Apparently new speed: 5.0
Actual new speed: 3.8000000000000043
---------------------------------------------
Wanted new speed: 5.0
Apparently new speed: 5.0
Actual new speed: 3.799999999999997
---------------------------------------------
Wanted new speed: 5.0
Apparently new speed: 5.0
Actual new speed: 3.8000000000000043

Related

Accessing CPU temperature in python

I need an example code for accessing CPU temperature in python.
I'm running windows 7, BTW.
Use the WMI module + Open Hardware Monitor + its WMI interface described here.
Sample code:
import wmi
w = wmi.WMI(namespace="root\OpenHardwareMonitor")
temperature_infos = w.Sensor()
for sensor in temperature_infos:
if sensor.SensorType==u'Temperature':
print(sensor.Name)
print(sensor.Value)
Download http://openhardwaremonitor.org/downloads/ and http://www.cputhermometer.com/ and extract OpenHardwareMonitorLib.dll and CPUThermometerLib.dll and place these in a directory.
You can then use the pythonnet module to address the .dlls and pull any stat that these programs offer. cputhermometer offers per-core CPU temps, openhardwaremonitor offers everything else. No need to use WMI which requires the program to be active in the background.
I have written a small script (python 3.6.5) to show every temperature sensor available on the system, you can of course easily modify this for other sensor types. You must run this as administrator:
import clr #package pythonnet, not clr
openhardwaremonitor_hwtypes = ['Mainboard','SuperIO','CPU','RAM','GpuNvidia','GpuAti','TBalancer','Heatmaster','HDD']
cputhermometer_hwtypes = ['Mainboard','SuperIO','CPU','GpuNvidia','GpuAti','TBalancer','Heatmaster','HDD']
openhardwaremonitor_sensortypes = ['Voltage','Clock','Temperature','Load','Fan','Flow','Control','Level','Factor','Power','Data','SmallData']
cputhermometer_sensortypes = ['Voltage','Clock','Temperature','Load','Fan','Flow','Control','Level']
def initialize_openhardwaremonitor():
file = 'OpenHardwareMonitorLib.dll'
clr.AddReference(file)
from OpenHardwareMonitor import Hardware
handle = Hardware.Computer()
handle.MainboardEnabled = True
handle.CPUEnabled = True
handle.RAMEnabled = True
handle.GPUEnabled = True
handle.HDDEnabled = True
handle.Open()
return handle
def initialize_cputhermometer():
file = 'CPUThermometerLib.dll'
clr.AddReference(file)
from CPUThermometer import Hardware
handle = Hardware.Computer()
handle.CPUEnabled = True
handle.Open()
return handle
def fetch_stats(handle):
for i in handle.Hardware:
i.Update()
for sensor in i.Sensors:
parse_sensor(sensor)
for j in i.SubHardware:
j.Update()
for subsensor in j.Sensors:
parse_sensor(subsensor)
def parse_sensor(sensor):
if sensor.Value is not None:
if type(sensor).__module__ == 'CPUThermometer.Hardware':
sensortypes = cputhermometer_sensortypes
hardwaretypes = cputhermometer_hwtypes
elif type(sensor).__module__ == 'OpenHardwareMonitor.Hardware':
sensortypes = openhardwaremonitor_sensortypes
hardwaretypes = openhardwaremonitor_hwtypes
else:
return
if sensor.SensorType == sensortypes.index('Temperature'):
print(u"%s %s Temperature Sensor #%i %s - %s\u00B0C" % (hardwaretypes[sensor.Hardware.HardwareType], sensor.Hardware.Name, sensor.Index, sensor.Name, sensor.Value))
if __name__ == "__main__":
print("OpenHardwareMonitor:")
HardwareHandle = initialize_openhardwaremonitor()
fetch_stats(HardwareHandle)
print("\nCPUMonitor:")
CPUHandle = initialize_cputhermometer()
fetch_stats(CPUHandle)
Here is the output on my system:
OpenHardwareMonitor:
SuperIO Nuvoton NCT6791D Temperature Sensor #0 CPU Core - 42.0°C
SuperIO Nuvoton NCT6791D Temperature Sensor #1 Temperature #1 - 35.0°C
SuperIO Nuvoton NCT6791D Temperature Sensor #2 Temperature #2 - 34.0°C
SuperIO Nuvoton NCT6791D Temperature Sensor #3 Temperature #3 - 25.0°C
SuperIO Nuvoton NCT6791D Temperature Sensor #4 Temperature #4 - 101.0°C
SuperIO Nuvoton NCT6791D Temperature Sensor #5 Temperature #5 - 16.0°C
SuperIO Nuvoton NCT6791D Temperature Sensor #6 Temperature #6 - 14.0°C
GpuNvidia NVIDIA GeForce GTX 1070 Temperature Sensor #0 GPU Core - 60.0°C
HDD ST31000528AS Temperature Sensor #0 Temperature - 37.0°C
HDD WDC WD20EARX-00PASB0 Temperature Sensor #0 Temperature - 36.0°C
HDD WDC WDS100T2B0B-00YS70 Temperature Sensor #0 Temperature - 40.0°C
HDD WDC WD80EFZX-68UW8N0 Temperature Sensor #0 Temperature - 31.0°C
HDD WDC WD30EFRX-68EUZN0 Temperature Sensor #0 Temperature - 30.0°C
HDD WDC WD80EFZX-68UW8N0 Temperature Sensor #0 Temperature - 33.0°C
HDD Crucial_CT256MX100SSD1 Temperature Sensor #0 Temperature - 40.0°C
CPUMonitor:
CPU Intel Core i7-8700K Temperature Sensor #0 CPU Core #1 - 39.0°C
CPU Intel Core i7-8700K Temperature Sensor #1 CPU Core #2 - 38.0°C
CPU Intel Core i7-8700K Temperature Sensor #2 CPU Core #3 - 37.0°C
CPU Intel Core i7-8700K Temperature Sensor #3 CPU Core #4 - 41.0°C
CPU Intel Core i7-8700K Temperature Sensor #4 CPU Core #5 - 36.0°C
CPU Intel Core i7-8700K Temperature Sensor #5 CPU Core #6 - 47.0°C
For further documentation (however you should be able to infer everything you need from the above code), refer to the https://github.com/openhardwaremonitor/openhardwaremonitor/ (or cputhermometer, on the website) source code, the functions and methods are identical when you use these with python.
I haven't tested this on any other computers, so different processor architectures may not function identically.
Ensure you run Hardware[x].Update() between taking measurements (and SubHardware[x].Update() if needed).
You can use pywin32 to access the native Windows API. I believe it should be possible to query the Windows API for the CPU temperature if the manufacturer for your mainboard driver registers a WMI Data Provider through their driver. Assuming this is the case you could download the pywin32 extensions and the Python WMI module mentioned in the answer by ars, and then proceed as follows:
import wmi
w = wmi.WMI()
print w.Win32_TemperatureProbe()[0].CurrentReading
Looking at the IronPython script in the ars' answer there seems to be another way to do it too, using a different WMI object. Using the same API and approach you could try receiving the temperature value with
w = wmi.WMI(namespace="root\wmi")
temperature_info = w.MSAcpi_ThermalZoneTemperature()[0]
print temperature_info.CurrentTemperature
which apparently should return the temperature value in tenths of Kelvin, thus to receive the degree in Celsius I guess you just divide this value by 10 and subtract ~273.
Check out the cputemp library.
EDIT: on windows, you might be able to convert this IronPython script which uses WMI using the python WMI library.
The code offered by eadmaster may work for older CPUs that OpenHardwareMonitor has been programmed for, but I have a Skylake i7 6700K CPU. OpenHardwareMonitor offered no results for me. However, there is a fork of this program called CPU Thermometer, which is based on OpenHardwareMonitor which does recognize my CPU.
In chasing down how to get CPU temps via Python, I switched to IronPython in order to have access to the .Net framework and have easy access to other performance data, but it should be fairly easy to figure out how to retro fit it for vanilla Python 2.7 (Just run CPU Thermometer instead ofOpenHardwareMonitor and change your namespace to "root\CPUThermometer"? Could it be that simple?).
#
# CPU Temp --REQUIRES CPU TEMPERATURE TO BE RUNNING!--
#
import clr
clr.AddReference('System.Management')
from System.Management import (ManagementScope, ManagementObject, ManagementObjectSearcher, WqlObjectQuery)
scope = ManagementScope("root\CPUThermometer")
searcher = ManagementObjectSearcher(scope,
WqlObjectQuery("SELECT * FROM Sensor Where SensorType LIKE 'Temperature'"), None)
mo = ManagementObject()
print "\n"
print " Temp Min Max"
strout = str(' ')
for mo in searcher.Get():
strout = '{0} {1} C {2} C {3} C\n{4}'.format(mo["Name"], mo["Value"], mo["Min"], mo["Max"], strout)
print strout
Sample Output:
D:\IronPython 2.7>ipy64 c:\users\neamerjell\desktop\test.py
Temp Min Max
CPU Core #1 21.0 C 20.0 C 37.0 C
CPU Core #2 23.0 C 21.0 C 39.0 C
CPU Core #3 21.0 C 20.0 C 32.0 C
CPU Core #4 21.0 C 20.0 C 36.0 C
I found out the hard way that the query is not quite standard SQL and DOES NOT LIKE the "Order By" clause, so I had to do some fancy string formatting to get the order correct as the query returns the cores in reverse order. This baffled me for a bit until I devised this way around it.

Why does he uses a floating point in this example?

I am a beginner learning Python from Learn Python the hard way. It's my first programming language that I learn and I am stuck at an exercise.
Exercise:
"Explain why the 4.0 is used instead of just 4."
cars = 100
space_in_a_car = 4.0 #Why does he uses 4.0 instead of 4 here?
drivers = 30
passengers = 90
cars_not_driven = cars - drivers
cars_driven = drivers
carpool_capacity = cars_driven * space_in_a_car
average_passengers_per_car = passengers / cars_driven
print "There are", cars, "cars available."
print "There are only", drivers, "drivers available."
print "There will be", cars_not_driven, "empty cars today."
print "We can transport", carpool_capacity, "people today."
print "We have", passengers, "to carpool today."
print "We need to put about", average_passengers_per_car, "in each car."
I honestly can't find any reason why he would use a floating point at line 2 other than to to serve as an example that if I have a floating point number it affects the rest of the expression evaluation(cars_driven * space_in_a_car) resulting in 120.0.
Am I missing something?
This was a simple question with a simple answer that I over-complicated for some reason.
(Assuming that you know why 3/4 returns 0 and why 3/4.0 returns 0.75)
I took a look at the book and the code is only that bit, it doesn't seem to have any more to it, and it does ask:
Explain why the 4.0 is used instead of
just 4.
It turns out this is a strange question since there is actually no reason for it. David Heffernan was right all along.
So, when you add the .0, it doesn't have any effect than turning the carpool capacity in a float since you just do:
carpool_capacity = cars_driven * space_in_a_car
I can't understand what the author was aiming for, the only notable difference is again that one prints 120.0 and the other 120
As I pointed out before:
average_passengers_per_car = passengers / float(cars_driven) #added float
Would make (more) sense since, for example if the passengers = 93 in the original code the average would be 3 and not 3.1 that would be in my opinion more reasonable for an average.
Sorry for the confusion, I hope I got it right now :) and that it helps!
OLD:
The reason probably this:
3/4 # returns 0
That is because int/int == int, so, 4 "fits" 0 times in 3, and no decimal point because it is an int.
You should do:
3/4. # returns 0.75
or
3/float(4)
This applies for python 2.x and not for python 3
BUT
This doesn't make sense at all, and unless I'm missing something I think it is "wrong"!
This would make much more sense:
cars = 100
space_in_a_car = 4 #not float
drivers = 30
passengers = 90
cars_not_driven = cars - drivers
cars_driven = drivers
carpool_capacity = cars_driven * space_in_a_car
average_passengers_per_car = passengers / float(cars_driven) #added float
Since the amount of space in a car couldn't be 4 and a half seats, and the average, could be 2 and half persons, since it is a number and not actually persons.
In the code as given in your question, there is no good reason for using a floating point value.
In general, integer div is not the same than floating point div
integer div:
myInt = 4 / 5
myInt == 0
float div:
myFloat = 4.0 / 5.0
myFloat = 0.8
by making space_in_car a float, then the results of the operations are calculated as floats (no rounding)
But in this sample space_in_car is only used for multiplication .For multiplication the same goes, but the value does not change (120 is the same than 120.0). My guess is that it was intended to be used in a division to show the above mentioned properties but there was a lapsus calami.
I think there is an error in the wording: since space_in_a_car appears only in a multiplication, there is no possibility to observe a problem when changing its value.
A problem could be observed if the value of drivers was not a divisor of the value of passengers
See what happens when changing the value of drivers :
form = ('space_in_a_car : %s\n'
'drivers : %s\n'
'passengers : %s\n'
'cars_driven : %s\n'
'average_passengers_per_car : %s\n\n')
for nbdrivers in (30, 30.0, 47, 47.0):
cars = 100
space_in_a_car = 4
drivers, passengers = nbdrivers, 90
cars_driven = drivers
carpool_capacity = cars_driven * space_in_a_car
average_passengers_per_car = passengers / cars_driven
print form % (space_in_a_car,
drivers,
passengers,
cars_driven,
average_passengers_per_car)
result
space_in_a_car : 4
drivers : 30
passengers : 90
cars_driven : 30
average_passengers_per_car : 3
space_in_a_car : 4
drivers : 30.0
passengers : 90
cars_driven : 30.0
average_passengers_per_car : 3.0
space_in_a_car : 4
drivers : 47
passengers : 90
cars_driven : 47
average_passengers_per_car : 1
space_in_a_car : 4
drivers : 47.0
passengers : 90
cars_driven : 47.0
average_passengers_per_car : 1.91489361702
Then , it is drivers that must be a float, not space_in_a_car
cars = 100
space_in_a_car = 4.0
drivers = 30
passengers = 90
# 90 % 4 = 2(man), 90 / 4.0 = 22.5(car)
print "Need %d cars." % int(round(90 / 4.0))
# He wants you to think more about it.

More efficient way of calculating data from pandas dataframe (stock)

I was wondering if there is a more efficient/cleaner way of doing the following. Say I have a dataframe that contains 2 columns, the percentage, (base on previous price) and the action, play/buy (1) or not play/sell (-1). Its basically about stocks.
For simplicity, consider the example df:
Percent Action
1.25 1
1.20 1
0.50 -1
0.75 1
I would like to generate the following. I only care about the final money amount, I am just showing this table for reference. Say we started with $100 and a state of not playing. Thus we should get the money amount of:
Playing Percent Action Money
No 1.25 1 $100
Yes 1.20 1 $120
Yes 0.50 -1 $60
No 0.75 1 $60
Yes ... ... ...
The amount didnt change in the first row since we weren't playing yet. Since the action is 1, we will play the next one. The percentage went up 20%, thus we get $120. The next action is still a 1, so we'll still be in the next one. The percentage went down to 50% so we end up with $60. Next action is -1, thus we will not play. The percentage went down to 75%, but since we weren't playing, our money stayed the same. And so on.
Currently, I have the code below. It works fine, but just wondering if there is a more efficient way using numpy/pandas functions. Mine basically iterates through each row and calculate the value.
playing = False
money = 10000
for index, row in df.iterrows():
## UPDATE MONEY IF PLAYING
if index > 0 and playing == True:
money = float(format(money*row['Percent'],'.2f'))
## BUY/SELL
if row['Action'] == 1:
if playing == False:
playing = True ## Buy, playing after this
elif row['Action'] == -1:
if playing == True:
playing = False ## Sell, not playing after this
You could try this:
# decide whether to play based on action
df['Playing'] = df.Action.shift().eq(1)
# replace Percent for not playing row with 1 and then calculate the cumulative product
df['Money'] = '$' + df.Percent.where(df.Playing, 1).cumprod().mul(100).astype(str)
df
#Percent Action Playing Money
#0 1.25 1 False $100.0
#1 1.20 1 True $120.0
#2 0.50 -1 True $60.0
#3 0.75 1 False $60.0

Highest possible value of combinations of 5

According to https://www.heroescounters.com/teampicker a Hero has a synergy value with another hero, Heroes of the Storm have 60+ heroes each one with a synergy value for example:
HeroID Synergy.With.HeroID Synergy.Points
1 2 97
1 3 95
1 4 94
45 1 2
45 2 11
A Team in heroes of the storm have 5 heroes, and the full synergy of a team is calculated by the formula:
Team_total_synergy = Synergy_Points(Hero1 with Hero2) +
mean(Synergy_Points(Hero3 + Hero1) + Synergy_Points(Hero3 + Hero2)) +
mean(Synergy_Points(Hero4 + Hero1) + Synergy_Points(Hero4 + Hero2) + Synergy_Points(Hero4 + Hero3)
[And so on... till Hero5]
Explaining the formula: Each Synergy Value after the synergy of Hero 1 and Hero 2 is calculated by the Mean of that Hero with the rest of the team, When Hero5 is added up i got the synergy of the team summing all the values.
My Answer is, How can I find(With Python or R) the Team with the greatest possible synergy given that formula, and how can I write the code to find it given the possibility there are 64 Heroes(approximately).
The easiest way is to brute force it by counting all 64^5 combinations of heroes and calculating their total synergy score. However this would take a few minutes to an hour on most computers.
The more efficient approach is to first sort the Synergy.Points column highest to lowest. Then the problem becomes finding a 'path' of five heroes such that the highest position in the path is as low as possible on the table (ie associated with the most synergy).
A path is a list of heroes such that you jump from hero to associated hero until you have five unique heroes. In the below table, a path would be 1 -> 2 -> 5 -> 6 -> 7. The positions in the table associated with this path is 1, 4, 5, 2 where the highest point is 5.
This will guarantee that the total synergy is highest.
HeroID Synergy.With.HeroID Synergy.Points
1 2 97
6 7 95
1 4 94
2 5 11
5 6 2
As for the python code, this is a little trickier.... I tried working this out for about 20 minutes but I realize there are a lot of complications. For example, a path might have a cycle which might create an infinite loop if your program isn't careful.
If you want to do this process once to find the most efficient team for this game, I'd try the brute force method. If you want to be able to run this code over and over again, I'd pose this to the Computer Science stackoverflow and get and algorithm to do this in python.
I hope that helps : )

SQLAlchemy: Aggregation query in pandas sql_query

Model: League has many Season has many Round has many Game has two one-to-one relationship with Team.
Total goals per game is saved in an SQLAlchemy column_property.
I can't see to figure out how to pass in the right query to pandas read_sql. All the variations I'm trying aren't working, including this:
pandoc = pd.read_sql(Match.query.join(Round).
join(Season).
join(League).filter(Match.round).filter(Round.season).filter(Season.league)
.statement, db.session.bind)
Which outputs the following: (I've dropped some rounds)
total_goals round_id home_goals away_goals finished
0 1.0 sxxx-0 1.0 0.0 True
1 0.0 sxxx-0 0.0 0.0 True
2 2.0 sxxx-0 2.0 0.0 True
3 3.0 sxxx-0 3.0 0.0 True
What I want Ideally is:
League total_goals
league.name total_goals (across all seasons)
Trying to traverse from League downwards seems more logical, but that hasn't worked either.
This worked, but I'm not sure if it's the "best" way:
pandoc = pd.read_sql(League.query.
join(Season).
join(Round).
join(Match).with_entities(func.sum(Match.total_goals).label('total_goals'), League.name).
group_by(League.name).
statement, db.session.bind)

Resources