add program to approximate cell configuration
This commit is contained in:
commit
d483a77903
|
@ -0,0 +1,28 @@
|
|||
Label;Capacity @ 2A;+Capacity @ .5A;Capacity;Resistance [mOhm]
|
||||
1 Gruen;1338;582;1920;170
|
||||
2 Gruen;1228;702;1930;150
|
||||
3 dunkelblau;1033;469;1502;140
|
||||
4 dunkelblau;438;395;833;212
|
||||
5 dunkelblau;777;411;1188;196
|
||||
6 dunkelblau;1201;382;1583;140
|
||||
7 dunkelblau;964;493;1457;200
|
||||
8 dunkelblau;955;543;1498;208
|
||||
9 dunkelblau;806;402;1208;174
|
||||
10 dunkelblau;1010;426;1436;166
|
||||
11 hellblau;1308;254;1562;118
|
||||
12 hellblau;1440;172;1612;118
|
||||
13 hellblau;1393;178;1571;114
|
||||
14 hellblau;1131;590;1721;286
|
||||
15 hellblau;1415;225;1640;110
|
||||
16 hellblau;1454;261;1715;110
|
||||
17 hellblau;1454;211;1665;108
|
||||
18 hellblau;1565;184;1749;100
|
||||
19 hellblau;1591;221;1812;110
|
||||
20 hellblau;1538;180;1718;118
|
||||
21 hellblau;1525;183;1708;108
|
||||
22 hellblau;1435;213;1648;126
|
||||
23 hellblau;1450;169;1619;122
|
||||
24 hellblau;1503;196;1699;112
|
||||
25 hellblau;1510;188;1698;130
|
||||
26 hellblau;1462;230;1692;130
|
||||
27 hellblau;1484;182;1666;112
|
|
|
@ -0,0 +1,25 @@
|
|||
Label;Capacity @ 2A;+Capacity @ .5A;Capacity;Resistance [mOhm]
|
||||
1 Gruen;1338;582;1920;170
|
||||
2 Gruen;1228;702;1930;150
|
||||
3 dunkelblau;1033;469;1502;140
|
||||
5 dunkelblau;777;411;1188;196
|
||||
6 dunkelblau;1201;382;1583;140
|
||||
7 dunkelblau;964;493;1457;200
|
||||
9 dunkelblau;806;402;1208;174
|
||||
10 dunkelblau;1010;426;1436;166
|
||||
11 hellblau;1308;254;1562;118
|
||||
12 hellblau;1440;172;1612;118
|
||||
13 hellblau;1393;178;1571;114
|
||||
15 hellblau;1415;225;1640;110
|
||||
16 hellblau;1454;261;1715;110
|
||||
17 hellblau;1454;211;1665;108
|
||||
18 hellblau;1565;184;1749;100
|
||||
19 hellblau;1591;221;1812;110
|
||||
20 hellblau;1538;180;1718;118
|
||||
21 hellblau;1525;183;1708;108
|
||||
22 hellblau;1435;213;1648;126
|
||||
23 hellblau;1450;169;1619;122
|
||||
24 hellblau;1503;196;1699;112
|
||||
25 hellblau;1510;188;1698;130
|
||||
26 hellblau;1462;230;1692;130
|
||||
27 hellblau;1484;182;1666;112
|
|
|
@ -0,0 +1,109 @@
|
|||
#!/usr/bin/env python3
|
||||
import numpy as np
|
||||
import csv
|
||||
import itertools
|
||||
import math
|
||||
|
||||
column_label=0
|
||||
column_capacity=3
|
||||
column_resistance=4
|
||||
|
||||
|
||||
config_parallel=2
|
||||
config_cells=12
|
||||
|
||||
#config_parallel*config_cells*config_packs needed
|
||||
batteriesneeded=config_parallel*config_cells
|
||||
|
||||
|
||||
batteries=[]
|
||||
batterylabels=[]
|
||||
|
||||
with open('12S_LiIon_Akkupack_selected.csv', 'r') as csvfile:
|
||||
csvreader = csv.reader(csvfile, delimiter=';')
|
||||
firstrow=True
|
||||
for row in csvreader:
|
||||
label=row[column_label]
|
||||
capacity=row[column_capacity]
|
||||
resistance=row[column_resistance]
|
||||
if not firstrow:
|
||||
capacity=float(capacity)
|
||||
resistance=float(resistance)
|
||||
|
||||
batteries.append([label,capacity,resistance])
|
||||
batterylabels.append(label)
|
||||
firstrow=False
|
||||
|
||||
print(str(len(batteries))+" Batteries found")
|
||||
if len(batteries)==batteriesneeded:
|
||||
print("You have just enough batteries")
|
||||
elif len(batteries)>batteriesneeded:
|
||||
print("You have "+str(len(batteries)-batteriesneeded)+" batteries spare")
|
||||
elif len(batteries)<batteriesneeded:
|
||||
print("You need "+str(batteriesneeded-len(batteries))+" more batteries!")
|
||||
exit()
|
||||
|
||||
#batteries=[["a",1],["b",2],["c",3],["d",4],["e",5],["f",6]]
|
||||
|
||||
bestcombination=[]
|
||||
bestdist=100000000
|
||||
|
||||
combinations=[]
|
||||
|
||||
|
||||
count=0
|
||||
|
||||
for comb_parallel1 in itertools.combinations(batteries,config_parallel):
|
||||
rest1=[x for x in batteries if x not in comb_parallel1]
|
||||
count+=1
|
||||
print(count)
|
||||
for comb_parallel2 in itertools.combinations(rest1,config_parallel):
|
||||
rest2=[x for x in rest1 if x not in comb_parallel2]
|
||||
for comb_parallel3 in itertools.combinations(rest2,config_parallel):
|
||||
rest3=[x for x in rest2 if x not in comb_parallel3]
|
||||
for comb_parallel4 in itertools.combinations(rest3,config_parallel):
|
||||
rest4=[x for x in rest3 if x not in comb_parallel4]
|
||||
for comb_parallel5 in itertools.combinations(rest4,config_parallel):
|
||||
rest5=[x for x in rest4 if x not in comb_parallel5]
|
||||
for comb_parallel6 in itertools.combinations(rest5,config_parallel):
|
||||
rest6=[x for x in rest5 if x not in comb_parallel6]
|
||||
for comb_parallel7 in itertools.combinations(rest6,config_parallel):
|
||||
rest7=[x for x in rest6 if x not in comb_parallel7]
|
||||
for comb_parallel8 in itertools.combinations(rest7,config_parallel):
|
||||
rest8=[x for x in rest7 if x not in comb_parallel8]
|
||||
for comb_parallel9 in itertools.combinations(rest8,config_parallel):
|
||||
rest9=[x for x in rest8 if x not in comb_parallel9]
|
||||
for comb_parallel10 in itertools.combinations(rest9,config_parallel):
|
||||
rest10=[x for x in rest9 if x not in comb_parallel10]
|
||||
for comb_parallel11 in itertools.combinations(rest10,config_parallel):
|
||||
rest11=[x for x in rest10 if x not in comb_parallel11]
|
||||
for comb_parallel12 in itertools.combinations(rest11,config_parallel):
|
||||
combinations.append([comb_parallel1,comb_parallel2,comb_parallel3,comb_parallel4,comb_parallel5,comb_parallel6,comb_parallel7,comb_parallel8,comb_parallel9,comb_parallel10,comb_parallel11,comb_parallel12])
|
||||
|
||||
|
||||
|
||||
#evaluate current combination of comb_pack1 and comb_pack2
|
||||
print(str(len(combinations))+" Combinations")
|
||||
for i in combinations: #every combinations
|
||||
|
||||
seriescapacities=[]
|
||||
for s in i: #all series
|
||||
parallelcapacity=0
|
||||
for p in s: #all parallels
|
||||
parallelcapacity+=p[1]
|
||||
seriescapacities.append(parallelcapacity)
|
||||
|
||||
meancapacity=np.mean(seriescapacities)
|
||||
dist=0
|
||||
for c in seriescapacities:
|
||||
dist+=math.pow(abs(c-meancapacity),2)
|
||||
|
||||
if dist<bestdist:
|
||||
print(str(dist)+" "+str(seriescapacities))
|
||||
bestdist=dist
|
||||
bestcombination=i
|
||||
|
||||
print("best combination with "+str(bestdist)+" distance:")
|
||||
#print(bestcombination)
|
||||
for i in bestcombination:
|
||||
print(i)
|
|
@ -0,0 +1,104 @@
|
|||
#!/usr/bin/env python3
|
||||
import numpy as np
|
||||
import csv
|
||||
import itertools
|
||||
import math
|
||||
|
||||
#https://stackoverflow.com/questions/5360220/how-to-split-a-list-into-pairs-in-all-possible-ways
|
||||
def all_pairs(lst):
|
||||
if len(lst) < 2:
|
||||
yield lst
|
||||
return
|
||||
a = lst[0]
|
||||
for i in range(1,len(lst)):
|
||||
pair = (a,lst[i])
|
||||
for rest in all_pairs(lst[1:i]+lst[i+1:]):
|
||||
yield [pair] + rest
|
||||
|
||||
column_label=0
|
||||
column_capacity=3
|
||||
column_resistance=4
|
||||
|
||||
|
||||
config_parallel=2
|
||||
config_cells=12
|
||||
|
||||
#config_parallel*config_cells*config_packs needed
|
||||
batteriesneeded=config_parallel*config_cells
|
||||
|
||||
|
||||
batteries=[]
|
||||
batterylabels=[]
|
||||
|
||||
with open('12S_LiIon_Akkupack_selected.csv', 'r') as csvfile:
|
||||
csvreader = csv.reader(csvfile, delimiter=';')
|
||||
firstrow=True
|
||||
for row in csvreader:
|
||||
label=row[column_label]
|
||||
capacity=row[column_capacity]
|
||||
resistance=row[column_resistance]
|
||||
if not firstrow:
|
||||
capacity=float(capacity)
|
||||
resistance=float(resistance)
|
||||
|
||||
batteries.append([label,capacity,resistance])
|
||||
batterylabels.append(label)
|
||||
firstrow=False
|
||||
|
||||
print(str(len(batteries))+" Batteries found")
|
||||
if len(batteries)==batteriesneeded:
|
||||
print("You have just enough batteries")
|
||||
elif len(batteries)>batteriesneeded:
|
||||
print("You have "+str(len(batteries)-batteriesneeded)+" batteries spare")
|
||||
elif len(batteries)<batteriesneeded:
|
||||
print("You need "+str(batteriesneeded-len(batteries))+" more batteries!")
|
||||
exit()
|
||||
|
||||
#batteries=[["a",1],["b",2],["c",3],["d",4],["e",5],["f",6]]
|
||||
|
||||
bestcombination=[]
|
||||
bestdist=100000000
|
||||
|
||||
|
||||
combinations=all_pairs(batteries)
|
||||
|
||||
num_combinations=0
|
||||
#print("Counting combinations")
|
||||
#for i in combinations: #just count the combinations
|
||||
# num_combinations+=1
|
||||
|
||||
print(str(num_combinations)+" combinations possible")
|
||||
|
||||
#evaluate combinations
|
||||
count=0
|
||||
for i in combinations: #every combinations
|
||||
count+=1
|
||||
if count%1000000==0:
|
||||
print(str(count)+"/"+str(num_combinations))
|
||||
|
||||
seriescapacities=[]
|
||||
for s in i: #all series
|
||||
parallelcapacity=0
|
||||
for p in s: #all parallels
|
||||
parallelcapacity+=p[1]
|
||||
seriescapacities.append(parallelcapacity)
|
||||
|
||||
meancapacity=np.mean(seriescapacities)
|
||||
dist=0
|
||||
for c in seriescapacities:
|
||||
dist+=math.pow(abs(c-meancapacity),2)
|
||||
|
||||
if dist<bestdist:
|
||||
print(str(count)+"/"+str(num_combinations)+" New Best with distance "+str(dist))
|
||||
bestdist=dist
|
||||
bestcombination=i
|
||||
print("## Combination ##")
|
||||
for i in bestcombination:
|
||||
print(i)
|
||||
print("## ----------- ##")
|
||||
|
||||
print("")
|
||||
print("best combination with "+str(bestdist)+" distance:")
|
||||
#print(bestcombination)
|
||||
for i in bestcombination:
|
||||
print(i)
|
|
@ -0,0 +1,157 @@
|
|||
#!/usr/bin/env python3
|
||||
import numpy as np
|
||||
import csv
|
||||
import itertools
|
||||
import math
|
||||
|
||||
distancemeasure="max" #mse, max
|
||||
|
||||
|
||||
column_label=0
|
||||
column_capacity=3
|
||||
column_resistance=4
|
||||
|
||||
|
||||
config_parallel=2
|
||||
config_cells=12
|
||||
|
||||
#config_parallel*config_cells*config_packs needed
|
||||
batteriesneeded=config_parallel*config_cells
|
||||
|
||||
|
||||
batteries=[]
|
||||
batterylabels=[]
|
||||
|
||||
with open('12S_LiIon_Akkupack_selected.csv', 'r') as csvfile:
|
||||
csvreader = csv.reader(csvfile, delimiter=';')
|
||||
firstrow=True
|
||||
for row in csvreader:
|
||||
label=row[column_label]
|
||||
capacity=row[column_capacity]
|
||||
resistance=row[column_resistance]
|
||||
if not firstrow:
|
||||
capacity=float(capacity)
|
||||
resistance=float(resistance)
|
||||
|
||||
batteries.append([label,capacity,resistance])
|
||||
#batterylabels.append(label)
|
||||
firstrow=False
|
||||
|
||||
print(str(len(batteries))+" Batteries found")
|
||||
if len(batteries)==batteriesneeded:
|
||||
print("You have enough batteries for "+str(config_cells)+"S"+str(config_parallel)+"P")
|
||||
elif len(batteries)>batteriesneeded:
|
||||
print("You have "+str(len(batteries)-batteriesneeded)+" batteries in spare")
|
||||
elif len(batteries)<batteriesneeded:
|
||||
print("You need "+str(batteriesneeded-len(batteries))+" more batteries!")
|
||||
exit()
|
||||
|
||||
|
||||
#calculate mean capacity of all cells
|
||||
meancapacity=0
|
||||
for i in batteries:
|
||||
meancapacity+=i[1] #add capacities
|
||||
meancapacity/=len(batteries)
|
||||
print("Mean Capacity= "+str(meancapacity))
|
||||
|
||||
comb_parallel_all=[]
|
||||
for comb_parallel in itertools.combinations(batteries,config_parallel):
|
||||
comb_parallel_all.append(comb_parallel)
|
||||
|
||||
comb_parallel_all_meancapacities=[]
|
||||
for current_parallel in comb_parallel_all:
|
||||
#print(current_parallel)
|
||||
meancapacity_parallel=0
|
||||
for current_cell_from_parallel in current_parallel:
|
||||
meancapacity_parallel+=current_cell_from_parallel[1] #add capacities
|
||||
|
||||
meancapacity_parallel/=len(current_parallel)
|
||||
#print("Mean Capacity Parallel set="+str(meancapacity_parallel))
|
||||
comb_parallel_all_meancapacities.append( meancapacity_parallel )
|
||||
|
||||
deviationFromMean = [abs(x - meancapacity) for x in comb_parallel_all_meancapacities]
|
||||
assert len(comb_parallel_all)==len(deviationFromMean), "Menacapacity array lenght not matching"
|
||||
|
||||
sortedIndices=np.argsort(deviationFromMean)
|
||||
|
||||
|
||||
bestSelection=[]
|
||||
bestSelectionDistance=10000000000
|
||||
|
||||
def getDistanceFromSelection(selection):
|
||||
if distancemeasure=="mse":
|
||||
return getDistanceFromSelectionMSE(selection)
|
||||
elif distancemeasure=="max":
|
||||
return getDistanceFromSelectionMAX(selection)
|
||||
|
||||
def getDistanceFromSelectionMSE(selection): #Mean Squared Error
|
||||
global deviationFromMean
|
||||
distance=0
|
||||
for i in selection:
|
||||
distance+= math.pow(deviationFromMean[i],2)
|
||||
distance/=len(selection)
|
||||
return distance
|
||||
|
||||
def getDistanceFromSelectionMAX(selection): #Mean Squared Error
|
||||
global deviationFromMean
|
||||
_deviations=[deviationFromMean[x] for x in selection]
|
||||
distance=max(_deviations)
|
||||
return distance
|
||||
|
||||
def greedy(parallelCombinations,remainingSortedIndices,currentSelection):
|
||||
global config_cells
|
||||
global bestSelection
|
||||
global bestSelectionDistance
|
||||
global deviationFromMean
|
||||
#print("greedy("+str(len(parallelCombinations))+","+str(len(remainingSortedIndices))+","+str(currentSelection)+")")
|
||||
|
||||
if len(remainingSortedIndices)<1 or len(currentSelection)>=config_cells : #nothing left
|
||||
|
||||
currentSelectionDistance=getDistanceFromSelection(currentSelection)
|
||||
if currentSelectionDistance < bestSelectionDistance: #new best found
|
||||
bestSelectionDistance=currentSelectionDistance
|
||||
bestSelection=currentSelection
|
||||
print("")
|
||||
print("New best found "+str(currentSelection))
|
||||
_print_deviationFromMean=[round(deviationFromMean[a],1) for a in currentSelection]
|
||||
print("Dev. from mean "+str(_print_deviationFromMean))
|
||||
print("Distance="+str(currentSelectionDistance))
|
||||
for i in bestSelection:
|
||||
print(str(comb_parallel_all[i])+" mc="+str(comb_parallel_all_meancapacities[i]))
|
||||
|
||||
|
||||
return #backtrack
|
||||
|
||||
if len(currentSelection)>0 and getDistanceFromSelection(currentSelection)>bestSelectionDistance: #distance is already too high
|
||||
return #backtrack early
|
||||
|
||||
for i in remainingSortedIndices: #try all in sorted order
|
||||
newremainingSortedIndices=[x for x in remainingSortedIndices] #copy list, should be the same for every i
|
||||
|
||||
_selectedIndex=i #greedy take element i
|
||||
|
||||
|
||||
#remove elements with one of the used batteries
|
||||
for used in parallelCombinations[_selectedIndex]:
|
||||
#print(used)
|
||||
for rsi in newremainingSortedIndices: #check all remaining indices
|
||||
containesBattery=False
|
||||
for pcb in parallelCombinations[rsi]:
|
||||
if pcb==used:
|
||||
containesBattery=True
|
||||
|
||||
if containesBattery:
|
||||
newremainingSortedIndices=[x for x in newremainingSortedIndices if x is not rsi] #remove current index rsi from remainingSortedIndices
|
||||
|
||||
#repeat until empty
|
||||
greedy(parallelCombinations,newremainingSortedIndices,currentSelection+[_selectedIndex])
|
||||
|
||||
|
||||
|
||||
|
||||
greedy(comb_parallel_all,sortedIndices, [])
|
||||
print(bestSelection)
|
||||
|
||||
print("###")
|
||||
for i in bestSelection:
|
||||
print(str(comb_parallel_all[i])+" mc="+str(comb_parallel_all_meancapacities[i]))
|
|
@ -0,0 +1,67 @@
|
|||
#!/usr/bin/env python3
|
||||
import numpy as np
|
||||
import csv
|
||||
import itertools
|
||||
import math
|
||||
|
||||
import scipy.special
|
||||
|
||||
#o(n) = (n-1) * o(n-2) <- pairs
|
||||
def number_pairs(size):
|
||||
if size<2:
|
||||
return 1
|
||||
n=size-1
|
||||
return n*number_pairs(size-2)
|
||||
|
||||
|
||||
#https://stackoverflow.com/questions/5360220/how-to-split-a-list-into-pairs-in-all-possible-ways
|
||||
def all_pairs(lst):
|
||||
if len(lst) < 2:
|
||||
yield lst
|
||||
return
|
||||
a = lst[0]
|
||||
for i in range(1,len(lst)):
|
||||
pair = (a,lst[i])
|
||||
for rest in all_pairs(lst[1:i]+lst[i+1:]):
|
||||
yield [pair] + rest
|
||||
|
||||
def all_triples(lst):
|
||||
if len(lst) < 3:
|
||||
yield lst
|
||||
return
|
||||
a = lst[0]
|
||||
for i in range(1,len(lst)):
|
||||
for j in range(i+1,len(lst)):
|
||||
pair = (a,lst[i],lst[j])
|
||||
for rest in all_triples(lst[1:i]+lst[i+1:j]+lst[j+1:]):
|
||||
yield [pair] + rest
|
||||
|
||||
def all_quadruples(lst):
|
||||
if len(lst) < 4:
|
||||
yield lst
|
||||
return
|
||||
a = lst[0]
|
||||
for i in range(1,len(lst)):
|
||||
for j in range(i+1,len(lst)):
|
||||
for k in range(j+1,len(lst)):
|
||||
pair = (a,lst[i],lst[j],lst[k])
|
||||
for rest in all_quadruples(lst[1:i]+lst[i+1:j]+lst[j+1:k]+lst[k+1:]):
|
||||
yield [pair] + rest
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#a=[1,2,3,4]
|
||||
a=[1,2,3,4,5,6]
|
||||
|
||||
print(number_pairs(24))
|
||||
|
||||
|
||||
count=0
|
||||
for i in all_pairs(a):
|
||||
count+=1
|
||||
#print(i)
|
||||
|
||||
print(count)
|
|
@ -0,0 +1,71 @@
|
|||
import controlP5.*;
|
||||
import processing.serial.*;
|
||||
|
||||
ControlP5 cp5;
|
||||
|
||||
Serial myPort; // Create object from Serial class
|
||||
int val; // Data received from the serial port
|
||||
|
||||
float links;
|
||||
float rechts;
|
||||
Slider slLinks;
|
||||
Slider slRechts;
|
||||
|
||||
void setup() {
|
||||
size(450, 300);
|
||||
frameRate(100);
|
||||
background(0);
|
||||
|
||||
cp5 = new ControlP5(this);
|
||||
|
||||
slLinks = cp5.addSlider("links")
|
||||
.setRange((float)-1, (float)1)
|
||||
.setValue(0)
|
||||
.setPosition(10,10)
|
||||
.setSize(400,20)
|
||||
;
|
||||
|
||||
|
||||
slRechts = cp5.addSlider("rechts")
|
||||
.setRange((float)-1,(float)1)
|
||||
.setValue(0)
|
||||
.setPosition(10,40)
|
||||
.setSize(400,20);
|
||||
|
||||
cp5.addButton("stop")
|
||||
.setPosition(10, 80)
|
||||
.setSize(150, 150);
|
||||
|
||||
|
||||
myPort = new Serial(this, "/dev/ttyUSB0", 115200);
|
||||
}
|
||||
|
||||
void stop() {
|
||||
slLinks.setValue(0);
|
||||
slRechts.setValue(0);
|
||||
}
|
||||
|
||||
void draw() {
|
||||
|
||||
int bits = Float.floatToIntBits(rechts);
|
||||
byte[] bytes = new byte[8];
|
||||
bytes[0] = (byte)(bits & 0xff);
|
||||
bytes[1] = (byte)((bits >> 8) & 0xff);
|
||||
bytes[2] = (byte)((bits >> 16) & 0xff);
|
||||
bytes[3] = (byte)((bits >> 24) & 0xff);
|
||||
|
||||
bits = Float.floatToIntBits(links);
|
||||
bytes[4] = (byte)(bits & 0xff);
|
||||
bytes[5] = (byte)((bits >> 8) & 0xff);
|
||||
bytes[6] = (byte)((bits >> 16) & 0xff);
|
||||
bytes[7] = (byte)((bits >> 24) & 0xff);
|
||||
|
||||
myPort.write(bytes); // send an H to indicate mouse is over square
|
||||
|
||||
|
||||
String inBuffer = myPort.readString();
|
||||
if (inBuffer != null) {
|
||||
println(inBuffer);
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue