diff --git a/conf/userconf/tudelft/control_panel.xml b/conf/userconf/tudelft/control_panel.xml index b172fdc6d0..280fcfff4e 100644 --- a/conf/userconf/tudelft/control_panel.xml +++ b/conf/userconf/tudelft/control_panel.xml @@ -59,6 +59,7 @@ + diff --git a/sw/ground_segment/python/energy_mon/battery_model.py b/sw/ground_segment/python/energy_mon/battery_model.py new file mode 100755 index 0000000000..edbd1e688b --- /dev/null +++ b/sw/ground_segment/python/energy_mon/battery_model.py @@ -0,0 +1,67 @@ +#!/usr/bin/env python +# +# Copyright (C) 2018 TUDelft +# +# This file is part of paparazzi. +# +# paparazzi is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# paparazzi is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with paparazzi. If not, see . +# + +import os +import numpy as np + +PPRZ_SRC = os.getenv("PAPARAZZI_SRC", os.path.normpath(os.path.join(os.path.dirname(os.path.abspath(__file__)), + '../../../..'))) + + +batmodel = np.loadtxt(PPRZ_SRC + '/sw/ground_segment/python/energy_mon/batterymodel.csv', delimiter=',') + + +capacity = 3300 #mAh +cells_in_series = 6 #cells +cells_in_parallel = 6 #cells + + + +def index_from_volt(volt): + v = round(volt*100.0,0) + # 1/100 of volts + if v>420: + v=420 + elif v<251: + v=251 + + # index in a list from 420:-1:250 + index = 420 - v + return index + +def mah_from_volt_and_current(volt, current): + global batmodel + item = index_from_volt(volt) + mah = batmodel[item,1:] + + # interpolate between point 1 and 2 + m0 = mah[1] + a0 = 4.0 + dm = mah[1]-mah[0] + da = 2.0 + + return (current - a0) / da * dm + m0 + + +#print(mah_from_volt_and_current(3.6, 2.5)) + +#for i in batmodel[:,[0,3]]: +# print(i) + diff --git a/sw/ground_segment/python/energy_mon/batterymodel.csv b/sw/ground_segment/python/energy_mon/batterymodel.csv new file mode 100755 index 0000000000..0531c9a7bf --- /dev/null +++ b/sw/ground_segment/python/energy_mon/batterymodel.csv @@ -0,0 +1,172 @@ +4.20000000000000, 0, 0, 0, 0, 0 +4.19000000000000, 0.513834507658663, 0.388025038699490, 0.217714079016299, 0.118930088982257, 0 +4.18000000000000, 1.10317889372677, 0.833071789750540, 0.467422045927462, 0.255337393730335, 0 +4.17000000000000, 1.69252327979492, 1.27811854080163, 0.717130012838647, 0.391744698478424, 0 +4.16000000000000, 2.28186766586303, 1.72316529185268, 0.966837979749811, 0.528152003226501, 0 +4.15000000000000, 2.87121205193113, 2.16821204290373, 1.21654594666097, 0.664559307974578, 0 +4.14000000000000, 3.46055643799923, 2.61325879395478, 1.46625391357214, 0.800966612722655, 0 +4.13000000000000, 4.04990082406739, 3.05830554500587, 1.71596188048332, 0.937373917470744, 0 +4.12000000000000, 4.63924521013549, 3.50335229605691, 1.96566984739449, 1.07378122221882, 0 +4.11000000000000, 5.22858959620360, 3.94839904710796, 2.21537781430565, 1.21018852696690, 0 +4.10000000000000, 5.81793398227170, 4.39344579815901, 2.46508578121681, 1.34659583171498, 0 +4.09000000000000, 6.40727836833986, 4.83849254921010, 2.71479374812800, 1.48300313646306, 0 +4.08000000000000, 6.99662275440796, 5.28353930026115, 2.96450171503916, 1.61941044121114, 0 +4.07000000000000, 7.58596714047607, 5.72858605131220, 3.21420968195033, 1.75581774595922, 0 +4.06000000000000, 8.17531152654417, 6.17363280236325, 3.46391764886149, 1.89222505070730, 0 +4.05000000000000, 14.0523087852084, 6.61867955341434, 3.71362561577267, 2.02863235545538, 0 +4.04000000000000, 27.7507924127812, 7.06372630446539, 3.96333358268384, 2.16503966020346, 0 +4.03000000000000, 41.4492760403540, 7.50877305551644, 4.21304154959500, 2.30144696495154, 0 +4.02000000000000, 55.1477596679267, 7.95381980656749, 4.46274951650616, 2.43785426969962, 0 +4.01000000000000, 76.7050128995987, 8.39886655761857, 4.71245748341735, 2.57426157444771, 0 +4, 114.772377927802, 8.84391330866962, 4.96216545032851, 2.71066887919578, 0 +3.99000000000000, 163.593026767514, 9.28896005972067, 5.21187341723968, 2.84707618394386, 0 +3.98000000000000, 224.659424833591, 9.73400681077174, 5.46158138415085, 2.98348348869194, 0 +3.97000000000000, 285.725822899665, 10.1790535618228, 5.71128935106201, 3.11989079344002, 0 +3.96000000000000, 346.792220965742, 10.6241003128739, 5.96099731797319, 3.25629809818810, 0 +3.95000000000000, 409.661292397699, 11.0691470639249, 6.21070528488435, 3.39270540293618, 0 +3.94000000000000, 453.385191627012, 18.5463336019331, 6.46041325179552, 3.52911270768426, 0 +3.93000000000000, 486.240953109688, 32.4250604351327, 6.71012121870669, 3.66552001243234, 0 +3.92000000000000, 519.096714592363, 46.3037872683324, 6.95982918561786, 3.80192731718042, 0 +3.91000000000000, 551.952476075038, 84.5898468976653, 7.20953715252903, 3.93833462192850, 0 +3.90000000000000, 584.808237557712, 134.439967767930, 7.45924511944019, 4.07474192667658, 0 +3.89000000000000, 614.530873042205, 186.647864625303, 7.70895308635136, 4.21114923142466, 0 +3.88000000000000, 640.437829797509, 248.960515713133, 7.95866105326253, 4.34755653617274, 0 +3.87000000000000, 666.344786552814, 311.273166800966, 8.20836902017370, 4.48396384092082, 0 +3.86000000000000, 692.251743308119, 371.603545527798, 8.45807698708487, 4.62037114566890, 0 +3.85000000000000, 718.158700063425, 431.083803384367, 21.2907479305544, 4.75677845041698, 0 +3.84000000000000, 744.065656818729, 490.564061240934, 34.2682587356237, 4.89318575516506, 0 +3.83000000000000, 780.044896024484, 526.738013698630, 47.2457695406936, 5.02959305991314, 0 +3.82000000000000, 817.319190947932, 558.956486704269, 63.8562449637486, 5.16600036466122, 0 +3.81000000000000, 854.593485871382, 591.174959709910, 124.129572925067, 5.30240766940930, 0 +3.80000000000000, 892.414019596555, 623.393432715550, 205.882352941188, 5.43881497415738, 0 +3.79000000000000, 932.788497656771, 655.611905721191, 321.434528605975, 5.57522227890546, 0 +3.78000000000000, 973.162975716985, 688.024089231941, 381.906124093483, 9.76954069298807, 0 +3.77000000000000, 1013.53745377720, 721.416514695278, 442.377719580995, 17.7002417405306, 0 +3.76000000000000, 1053.93214694988, 754.808940158615, 494.453576864542, 25.6309427880728, 0 +3.75000000000000, 1094.51867584025, 788.201365621952, 533.225893096973, 33.5616438356153, 0 +3.74000000000000, 1135.10520473061, 821.593791085289, 571.998209329401, 54.3679828095617, 0 +3.73000000000000, 1175.69173362097, 854.986216548626, 609.811571313464, 83.4472199838828, 0 +3.72000000000000, 1216.27826251134, 888.378642011962, 643.437743755041, 206.096696212733, 4.83137254901893 +3.71000000000000, 1256.86479140170, 923.829046054674, 677.063916196620, 340.241740531847, 10.6472199838831 +3.70000000000000, 1297.45132029206, 962.262443438915, 710.690088638197, 414.660220252494, 16.4630674187470 +3.69000000000000, 1331.83014680489, 1000.69584082316, 744.316261079774, 475.462261616982, 22.2789148536110 +3.68000000000000, 1364.54428862600, 1039.12923820740, 777.942433521352, 524.032232070914, 28.0947622884751 +3.67000000000000, 1397.25843044712, 1077.56263559164, 811.568605962931, 563.119258662372, 40.3740934730036 +3.66000000000000, 1429.97257226823, 1112.03783027270, 845.194778404508, 602.206285253829, 59.2095084609196 +3.65000000000000, 1462.68671408934, 1145.43025573603, 878.820950846085, 641.293311845285, 78.0449234488355 +3.64000000000000, 1495.40085591045, 1178.82268119937, 912.850168270363, 680.380338436743, 237.597636314785 +3.63000000000000, 1528.06527113855, 1212.21510666271, 947.838555244816, 716.588607202627, 398.576954069302 +3.62000000000000, 1560.72109898137, 1245.60753212604, 982.826942219267, 750.751627099730, 451.825946817084 +3.61000000000000, 1593.37692682419, 1278.99995758938, 1017.81532919372, 784.914646996833, 505.074939564865 +3.60000000000000, 1626.03275466702, 1312.45017459038, 1052.80371616817, 819.077666893939, 550.614020950846 +3.59000000000000, 1658.68858250984, 1347.87397260274, 1087.79210314262, 853.240686791042, 593.439806607574 +3.58000000000000, 1691.34441035266, 1383.29777061510, 1123.13087168791, 888.022920583753, 636.265592264304 +3.57000000000000, 1726.15532024500, 1418.72156862745, 1159.51879414134, 922.829886292410, 678.145447219984 +3.56000000000000, 1762.75855584904, 1454.14536663981, 1195.90671659477, 957.636852001069, 715.816277195809 +3.55000000000000, 1799.36179145308, 1489.56916465216, 1232.29463904820, 992.443817709727, 753.487107171633 +3.54000000000000, 1835.96502705712, 1523.34139135106, 1268.68256150163, 1027.25078341839, 791.157937147458 +3.53000000000000, 1872.56826266116, 1556.38597904915, 1305.07048395506, 1062.05774912704, 828.828767123282 +3.52000000000000, 1911.37717617264, 1589.43056674725, 1340.37286059629, 1096.80298146656, 864.683319903299 +3.51000000000000, 1951.03068141035, 1622.47515444534, 1371.46120870266, 1131.49979854955, 900.371474617238 +3.50000000000000, 1990.68418664807, 1655.51974214343, 1402.54955680902, 1166.19661563255, 936.059629331179 +3.49000000000000, 2034.18797430334, 1688.56432984153, 1433.63790491539, 1200.89343271555, 971.747784045119 +3.48000000000000, 2078.93978735732, 1721.37652430835, 1464.72625302175, 1235.59024979855, 1007.43593875906 +3.47000000000000, 2123.69160041131, 1753.62804190169, 1495.81460112812, 1270.28706688154, 1042.55336605376 +3.46000000000000, 2168.44341346530, 1785.87955949503, 1526.90294923449, 1302.03146867976, 1075.71811588894 +3.45000000000000, 2213.19522651929, 1818.13107708837, 1557.99129734085, 1333.33686755163, 1108.88286572412 +3.44000000000000, 2258.14579594932, 1850.38259468171, 1589.07964544722, 1364.64226642351, 1142.04761555930 +3.43000000000000, 2303.25165815722, 1882.63411227505, 1620.96580177276, 1395.94766529539, 1175.21236539448 +3.42000000000000, 2348.35752036512, 1924.69782433521, 1654.59197421434, 1427.25306416727, 1208.37711522966 +3.41000000000000, 2393.46338257301, 1967.18372280419, 1688.21814665592, 1458.55846303914, 1241.54186506483 +3.40000000000000, 2438.56924478091, 2009.66962127316, 1721.84431909750, 1489.91136180499, 1274.70661490001 +3.39000000000000, 2483.67510698881, 2052.15551974214, 1755.47049153908, 1521.63416599516, 1307.80170829976 +3.38000000000000, 2523.46191089093, 2094.64141821112, 1789.09666398066, 1553.35697018533, 1340.79342465754 +3.37000000000000, 2560.06514649497, 2134.78314978959, 1822.72283642224, 1585.07977437550, 1373.78514101531 +3.36000000000000, 2596.66838209901, 2174.87724952995, 1856.34900886382, 1616.80257856567, 1406.77685737309 +3.35000000000000, 2633.27161770305, 2214.97134927030, 1889.97518130540, 1648.52538275584, 1439.76857373087 +3.34000000000000, 2669.87485330709, 2255.06544901066, 1924.93385099993, 1680.24818694601, 1472.76029008864 +3.33000000000000, 2697.53436632297, 2295.15954875101, 1961.70346494762, 1711.97099113618, 1505.75200644642 +3.32000000000000, 2722.99609073876, 2335.25364849136, 1998.47307889532, 1743.69379532635, 1538.74372280419 +3.31000000000000, 2748.45781515456, 2374.67526188558, 2035.24269284301, 1778.63062046737, 1571.73543916197 +3.30000000000000, 2773.91953957035, 2413.60779430078, 2072.01230679071, 1815.90491539082, 1605.60032232071 +3.29000000000000, 2799.38126398615, 2452.54032671599, 2108.78192073840, 1853.17921031426, 1640.29713940371 +3.28000000000000, 2824.84298840194, 2491.47285913119, 2145.55153468610, 1890.45350523771, 1674.99395648671 +3.27000000000000, 2850.30471281773, 2524.89003491807, 2182.32114863380, 1927.72780016116, 1709.69077356970 +3.26000000000000, 2868.21333824678, 2555.55541230191, 2220.54187799213, 1965.00209508461, 1744.38759065270 +3.25000000000000, 2883.65733502358, 2586.22078968574, 2259.72887140352, 2002.27639000806, 1779.08440773570 +3.24000000000000, 2899.10133180037, 2616.88616706957, 2298.91586481490, 2039.42734354016, 1813.78122481870 +3.23000000000000, 2914.54532857716, 2647.55154445341, 2338.10285822629, 2076.43728176202, 1848.47804190170 +3.22000000000000, 2929.98932535396, 2676.06107977439, 2377.28985163768, 2113.44721998389, 1883.17485898469 +3.21000000000000, 2945.43332213075, 2700.24971796939, 2416.47684504907, 2150.45715820575, 1918.84045124900 +3.20000000000000, 2960.87731890754, 2724.43835616439, 2451.76739188827, 2187.46709642761, 1954.52860596294 +3.19000000000000, 2973.05662342587, 2748.62699435939, 2483.93079058108, 2224.47703464947, 1990.21676067688 +3.18000000000000, 2983.87121576342, 2772.81563255439, 2516.09418927389, 2261.48697287134, 2025.90491539082 +3.17000000000000, 2994.68580810098, 2797.00427074939, 2548.25758796670, 2298.49691109320, 2061.59307010476 +3.16000000000000, 3005.50040043854, 2821.19290894439, 2580.42098665951, 2335.50684931506, 2098.16742770168 +3.15000000000000, 3016.31499277610, 2843.72958988930, 2612.58438535233, 2372.51678753693, 2136.93974393411 +3.14000000000000, 3027.12958511365, 2860.42580262097, 2643.62786609041, 2409.52672575879, 2175.71206016654 +3.13000000000000, 3037.94417745121, 2877.12201535264, 2668.50142846679, 2444.42707493956, 2214.48437639897 +3.12000000000000, 3048.75876978877, 2893.81822808431, 2693.37499084317, 2478.79344614558, 2253.25669263140 +3.11000000000000, 3057.72795092407, 2910.51444081598, 2718.24855321955, 2513.15981735160, 2292.02900886383 +3.10000000000000, 3065.14699383951, 2927.21065354765, 2743.12211559593, 2547.52618855762, 2330.80132509626 +3.09000000000000, 3072.56603675495, 2943.90686627932, 2767.99567797232, 2581.89255976364, 2367.04716310376 +3.08000000000000, 3079.98507967040, 2958.29716567986, 2792.86924034870, 2611.92999597100, 2402.96857373086 +3.07000000000000, 3087.40412258584, 2970.02081070666, 2817.74280272508, 2636.96127115231, 2438.88998435796 +3.06000000000000, 3094.82316550128, 2981.74445573346, 2840.06098307817, 2661.99254633361, 2474.81139498506 +3.05000000000000, 3102.24220841672, 2993.46810076026, 2857.19129734086, 2687.02382151492, 2510.73280561216 +3.04000000000000, 3109.66125133217, 3005.19174578706, 2874.32161160355, 2712.05509669622, 2546.65421623926 +3.03000000000000, 3117.08029424761, 3016.91539081386, 2891.45192586624, 2737.08637187753, 2577.10132957291 +3.02000000000000, 3124.49933716305, 3028.63903584066, 2908.58224012893, 2762.11764705884, 2606.51101262421 +3.01000000000000, 3131.91838007850, 3040.36268086746, 2925.71255439162, 2787.14892224014, 2635.92069567552 +3, 3139.23698020707, 3050.92368758767, 2942.84286865431, 2812.18019742145, 2665.33037872682 +2.99000000000000, 3144.31262887749, 3058.56065896678, 2959.97318291700, 2837.21147260275, 2694.74006177813 +2.98000000000000, 3149.38827754792, 3066.19763034590, 2977.10349717969, 2862.24274778406, 2724.14974482943 +2.97000000000000, 3154.46392621835, 3073.83460172501, 2991.51813053988, 2886.53337070386, 2753.55942788074 +2.96000000000000, 3159.53957488877, 3081.47157310412, 3002.47005103411, 2902.73958588797, 2782.96911093204 +2.95000000000000, 3164.61522355920, 3089.10854448323, 3013.42197152833, 2918.94580107207, 2809.80471157036 +2.94000000000000, 3169.69087222963, 3096.74551586235, 3024.37389202256, 2935.15201625618, 2830.79774375503 +2.93000000000000, 3174.76652090005, 3104.38248724146, 3035.32581251679, 2951.35823144029, 2851.79077593970 +2.92000000000000, 3179.84216957048, 3112.01945862058, 3046.27773301101, 2967.56444662439, 2872.78380812438 +2.91000000000000, 3184.91781824091, 3119.65642999969, 3057.22965350524, 2983.77066180850, 2893.77684030905 +2.90000000000000, 3189.99346691134, 3125.92186322163, 3068.18157399947, 2999.97687699261, 2914.76987249372 +2.89000000000000, 3195.06911558176, 3131.55010267473, 3076.66520157254, 3016.18309217671, 2934.09676067687 +2.88000000000000, 3200.14476425219, 3137.17834212783, 3085.07655116842, 3028.67873955638, 2948.68925060435 +2.87000000000000, 3205.22041292262, 3142.80658158092, 3093.48790076429, 3040.78349378684, 2963.28174053183 +2.86000000000000, 3210.29606159304, 3148.43482103402, 3101.89925036017, 3052.88824801730, 2977.87423045931 +2.85000000000000, 3215.37171026347, 3154.06306048711, 3110.31059995605, 3064.99300224777, 2992.46672038679 +2.84000000000000, 3220.44735893390, 3159.69129994021, 3118.72194955193, 3077.09775647823, 3007.05921031426 +2.83000000000000, 3225.52300760433, 3165.31953939330, 3127.13329914781, 3089.20251070869, 3021.65170024174 +2.82000000000000, 3230.59865627475, 3170.94777884640, 3135.54464874369, 3100.88530754768, 3036.24419016922 +2.81000000000000, 3235.12639576378, 3176.57601829949, 3143.95599833956, 3110.13779210315, 3050.83668009670 +2.80000000000000, 3239.09174628755, 3182.20425775259, 3152.36734793544, 3119.39027665862, 3064.08683699105 +2.79000000000000, 3243.05709681132, 3186.61294654848, 3160.77869753132, 3128.64276121408, 3075.04986490971 +2.78000000000000, 3247.02244733509, 3190.38947085683, 3168.37429492345, 3137.89524576955, 3086.01289282837 +2.77000000000000, 3250.98779785886, 3194.16599516519, 3173.33098307817, 3147.14773032501, 3096.97592074703 +2.76000000000000, 3254.95314838264, 3197.94251947354, 3178.28767123288, 3156.40021488048, 3107.93894866569 +2.75000000000000, 3258.91849890641, 3201.71904378189, 3183.24435938759, 3165.65269943595, 3118.90197658435 +2.74000000000000, 3262.88384943018, 3205.49556809025, 3188.20104754231, 3174.90518399141, 3129.86500450301 +2.73000000000000, 3266.84919995395, 3209.27209239860, 3193.15773569702, 3184.15766854688, 3140.82803242167 +2.72000000000000, 3270.81455047772, 3213.04861670696, 3198.11442385173, 3193.41015310234, 3151.79106034033 +2.71000000000000, 3274.77990100149, 3216.82514101531, 3203.07111200645, 3201.15167668754, 3162.75408825899 +2.70000000000000, 3278.74525152526, 3220.60166532366, 3208.02780016116, 3207.25221595488, 3173.71711617765 +2.69000000000000, 3282.71060204903, 3224.37818963202, 3212.98448831587, 3213.35275522222, 3184.68014409631 +2.68000000000000, 3286.67595257281, 3228.15471394037, 3217.94117647059, 3219.45329448956, 3194.21367430404 +2.67000000000000, 3290.64130309658, 3231.93123824873, 3222.89786462530, 3225.55383375690, 3200.04947318808 +2.66000000000000, 3294.60665362035, 3235.70776255708, 3227.85455278001, 3231.65437302424, 3205.88527207212 +2.65000000000000, 3298.57200414412, 3239.48428686543, 3232.81124093473, 3237.75491229158, 3211.72107095616 +2.64000000000000, 3302.53735466789, 3243.26081117379, 3237.76792908944, 3243.85545155892, 3217.55686984020 +2.63000000000000, 3306.50270519166, 3247.03733548214, 3242.72461724415, 3249.95599082626, 3223.39266872424 +2.62000000000000, 3310.24946982675, 3250.81385979050, 3247.68130539887, 3256.05653009360, 3229.22846760828 +2.61000000000000, 3313.13336111677, 3254.59038409885, 3252.63799355358, 3262.15706936094, 3235.06426649232 +2.60000000000000, 3316.01725240678, 3258.36690840720, 3257.59468170829, 3268.25760862828, 3240.90006537636 +2.59000000000000, 3318.90114369680, 3262.14343271556, 3262.55136986301, 3274.35814789562, 3246.73586426041 +2.58000000000000, 3321.78503498681, 3265.91995702391, 3267.50805801772, 3280.45868716295, 3252.57166314445 +2.57000000000000, 3324.66892627683, 3269.69648133227, 3272.46474617243, 3285.31093098589, 3258.40746202849 +2.56000000000000, 3327.55281756684, 3273.47300564062, 3277.42143432715, 3289.36589520098, 3264.24326091253 +2.55000000000000, 3330.43670885686, 3277.24952994897, 3282.37812248186, 3293.42085941607, 3270.07905979657 +2.54000000000000, 3333.32060014687, 3281.02605425733, 3287.33481063657, 3297.47582363116, 3275.91485868061 +2.53000000000000, 3336.20449143689, 3284.80257856568, 3292.29149879129, 3301.53078784626, 3281.75065756465 +2.52000000000000, 3339.08838272690, 3288.57910287404, 3297.24818694600, 3305.58575206135, 3287.58645644869 +2.51000000000000, 3341.97227401692, 3292.35562718239, 3302.20487510071, 3309.64071627644, 3293.42225533273 +2.50000000000000, 3344.85616530693, 3296.13215149074, 3307.16156325543, 3313.69568049153, 3299.25805421677 + diff --git a/sw/ground_segment/python/energy_mon/energy_mon.ico b/sw/ground_segment/python/energy_mon/energy_mon.ico new file mode 100755 index 0000000000..5190695bdc Binary files /dev/null and b/sw/ground_segment/python/energy_mon/energy_mon.ico differ diff --git a/sw/ground_segment/python/energy_mon/energy_mon.py b/sw/ground_segment/python/energy_mon/energy_mon.py new file mode 100755 index 0000000000..eee387fe6f --- /dev/null +++ b/sw/ground_segment/python/energy_mon/energy_mon.py @@ -0,0 +1,36 @@ +#!/usr/bin/env python +# +# Copyright (C) 2018 TUDelft +# +# This file is part of paparazzi. +# +# paparazzi is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# paparazzi is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with paparazzi. If not, see . +# + +import wx +import energy_mon_viewer + +class EnergyMonApp(wx.App): + def OnInit(self): + self.main = energy_mon_viewer.EnergyMonFrame() + self.main.Show() + self.SetTopWindow(self.main) + return True + +def main(): + application = EnergyMonApp(0) + application.MainLoop() + +if __name__ == '__main__': + main() diff --git a/sw/ground_segment/python/energy_mon/energy_mon_viewer.py b/sw/ground_segment/python/energy_mon/energy_mon_viewer.py new file mode 100644 index 0000000000..bc9e8a6efe --- /dev/null +++ b/sw/ground_segment/python/energy_mon/energy_mon_viewer.py @@ -0,0 +1,288 @@ +# +# Copyright (C) 2018 TUDelft +# +# This file is part of paparazzi. +# +# paparazzi is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# paparazzi is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with paparazzi. If not, see . +# + +import wx + +import sys +import os +import math + +import battery_model as bat + +PPRZ_HOME = os.getenv("PAPARAZZI_HOME", os.path.normpath(os.path.join(os.path.dirname(os.path.abspath(__file__)), + '../../../..'))) + +PPRZ_SRC = os.getenv("PAPARAZZI_SRC", os.path.normpath(os.path.join(os.path.dirname(os.path.abspath(__file__)), + '../../../..'))) + +sys.path.append(PPRZ_HOME + "/var/lib/python") + +from pprzlink.ivy import IvyMessagesInterface + +WIDTH = 600 +BARH = 140 + + +def QIColour(qi): + return { + 0: wx.Colour(64, 64, 64), # This channel is idle + 1: wx.Colour(128, 128, 128), # Searching + 2: wx.Colour(0, 128, 128), # Signal aquired + 3: wx.Colour(255, 0, 0), # Signal detected but unusable + 4: wx.Colour(0, 0, 255), # Code Lock on Signal + 5: wx.Colour(0, 255, 0), # Code and Carrier locked + 6: wx.Colour(0, 255, 0), # Code and Carrier locked + 7: wx.Colour(0, 255, 0), # Code and Carrier locked + }[qi] + + +class EnergyMessage(object): + def __init__(self, msg): + self.volt = float(msg['bat']) + self.current = float(msg['amp']) + self.power = float(msg['power']) + self.energy = float(msg['energy']) + +class TempMessage(object): + def __init__(self, msg): + self.motor = float(msg['temp1']) + self.battery = float(msg['temp2']) + +class BatteryCell(object): + def __init__(self): + self.voltage = 0; + self.current = 0; + self.energy = 0; + self.model = 0; + self.temperature = 0; + def fill_from_energy_msg(self, energy): + self.voltage = energy.volt / bat.cells_in_series + self.current = energy.current / bat.cells_in_parallel + self.energy = energy.energy / 6.0 + self.model = bat.mah_from_volt_and_current(self.voltage,self.current) + def fill_from_temp_msg(self, temp): + self.temperature = temp.battery + + def get_volt(self): + return "Cell Volt = "+str(round(self.voltage,2)) + " V" + def get_mah_from_volt(self): + return "Cap(U,I) = "+str(round(self.model/1000.0,2)) + " Ah" + def get_current(self): + return "Cell Amps = "+str(round(self.current,2)) + " A" + def get_energy(self): + return "Cell mAh = "+str(round(self.energy/1000.0 ,2)) + " Ah" + def get_temp(self): + return "Cell Temp = "+str(round(self.temperature ,2)) + + def get_volt_perc(self): + return (self.voltage - 2.5) / (4.2 - 2.5); + def get_current_perc(self): + return (self.current / 10) + def get_energy_perc(self): + return (self.energy / bat.capacity) + def get_model_perc(self): + return (self.model / bat.capacity) + def get_temp_perc(self): + return (self.temperature / 60); + + def get_volt_color(self): + if self.voltage < 3.4: + return 0.1 + elif self.voltage < 3.6: + return 0.5 + return 1 + + def get_current_color(self): + if self.current < 2.5: + return 1 + elif self.current > 4.5: + return 0.1 + return 0.5 + + def get_energy_color(self): + if self.energy > 3000: + return 0.1 + elif self.energy < 2000: + return 1 + return 0.5 + + def get_temp_color(self): + if (self.temperature > 20) & (self.temperature < 40): + return 1 + elif (self.temperature > 10) & (self.temperature < 50): + return 0.1 + return 0 + +class EnergyMonFrame(wx.Frame): + def message_recv(self, ac_id, msg): + if msg.name == "ENERGY": + self.bat = EnergyMessage(msg) + self.cell.fill_from_energy_msg(self.bat) + + wx.CallAfter(self.update) + elif msg.name == "TEMP_ADC": + self.temp = TempMessage(msg) + self.cell.fill_from_temp_msg(self.temp) + wx.CallAfter(self.update) + + def update(self): + self.Refresh() + + def OnSize(self, event): + self.w = event.GetSize()[0] + self.h = event.GetSize()[1] + self.Refresh() + + def StatusBox(self, dc, nr, txt, percent, color): + if percent < 0: + percent = 0 + if percent > 1: + percent = 1 + boxw = self.stat + tdx = int(boxw * 10.0 / 300.0) + tdy = int(boxw * 6.0 / 300.0) + boxh = int(boxw * 40.0 / 300.0) + boxw = self.stat - 2*tdx + spacing = boxh+10 + + dc.SetPen(wx.Pen(wx.Colour(0,0,0))) + dc.SetBrush(wx.Brush(wx.Colour(220,220,220))) + dc.DrawRectangle(tdx, int(nr*spacing+tdx), int(boxw), boxh) + if color < 0.2: + dc.SetBrush(wx.Brush(wx.Colour(250,0,0))) + elif color < 0.6: + dc.SetBrush(wx.Brush(wx.Colour(250,180,0))) + else: + dc.SetBrush(wx.Brush(wx.Colour(0,250,0))) +# dc.DrawLine(200,50,350,50) + dc.DrawRectangle(tdx, int(nr*spacing+tdx), int(boxw * percent), boxh) + dc.DrawText(txt,18,int(nr*spacing+tdy+tdx)) + + def plot_x(self, x): + return int(self.stat+self.tdx + x * (self.w-self.stat-2*self.tdx)) + + def plot_y(self, y): + return int(self.tdx + (1-y) * (self.h-self.tdx-self.tdx)) + + def plot(self, dc, i1, i2): + dc.DrawLine(self.plot_x(i1[1]/3500), self.plot_y((i1[0]-2.5)/(4.2-2.5)), self.plot_x(i2[1]/3500), self.plot_y((i2[0]-2.5)/(4.2-2.5))) + + def DischargePlot(self, dc): + self.tdx = int(self.stat * 10.0 / 300.0) + dc.SetPen(wx.Pen(wx.Colour(0,0,0),1)) + dc.SetBrush(wx.Brush(wx.Colour(250,250,250))) + dc.DrawRectangle(self.plot_x(0.0), self.plot_y(1.0), self.w-self.stat-2*self.tdx, self.h-2*self.tdx) + + for i in range(0,5): + dc.DrawLine(self.plot_x(0.0), self.plot_y(i/5.0), self.plot_x(1.0), self.plot_y(i/5.0)) + for i in range(0,7): + dc.DrawLine(self.plot_x(i/7.0), self.plot_y(0), self.plot_x(i/7.0), self.plot_y(1)) + + + dc.SetPen(wx.Pen(wx.Colour(255,180,0),4)) + dc.DrawLine(self.plot_x(self.cell.model/3500), self.plot_y(0), self.plot_x(self.cell.model/3500), self.plot_y(1)) + dc.DrawLine(self.plot_x(0.0), self.plot_y(self.cell.get_volt_perc()), self.plot_x(1.0), self.plot_y(self.cell.get_volt_perc())) + + thickness = 3 + dc.SetPen(wx.Pen(wx.Colour(0,0,0),thickness)) + li = bat.batmodel[0,[0,1]] + for i in bat.batmodel[:,[0,1]]: + self.plot(dc,li,i) + li=i + + dc.SetPen(wx.Pen(wx.Colour(0,0,255),thickness)) + li = bat.batmodel[0,[0,2]] + for i in bat.batmodel[:,[0,2]]: + self.plot(dc,li,i) + li=i + + dc.SetPen(wx.Pen(wx.Colour(0,255,0),thickness)) + li = bat.batmodel[0,[0,3]] + for i in bat.batmodel[:,[0,3]]: + self.plot(dc,li,i) + li=i + + dc.SetPen(wx.Pen(wx.Colour(255,255,0),thickness)) + li = bat.batmodel[0,[0,4]] + for i in bat.batmodel[:,[0,4]]: + self.plot(dc,li,i) + li=i + + dc.SetPen(wx.Pen(wx.Colour(255,0,0),thickness)) + li = bat.batmodel[0,[0,5]] + for i in bat.batmodel[:,[0,5]]: + self.plot(dc,li,i) + li=i + + + def OnPaint(self, e): + # Automatic Scaling + w = self.w + h = self.h + + self.stat = int(w/4) + if self.stat<100: + self.stat=100 + + dc = wx.PaintDC(self) + brush = wx.Brush("white") + dc.SetBackground(brush) + dc.Clear() + + # Background + dc.SetBrush(wx.Brush(wx.Colour(0, 0, 0), wx.TRANSPARENT)) + + fontscale = int(w * 11.0 / 800.0) + if fontscale < 6: + fontscale = 6 + font = wx.Font(fontscale, wx.FONTFAMILY_ROMAN, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_BOLD) + dc.SetFont(font) + + self.StatusBox(dc,0, self.cell.get_volt(), self.cell.get_volt_perc(), self.cell.get_volt_color()) + self.StatusBox(dc,1, self.cell.get_current(), self.cell.get_current_perc(), self.cell.get_current_color() ) + self.StatusBox(dc,2, self.cell.get_energy(), self.cell.get_energy_perc(), self.cell.get_energy_color() ) + self.StatusBox(dc,3, self.cell.get_mah_from_volt(), self.cell.get_energy_perc(), self.cell.get_energy_color() ) + self.StatusBox(dc,4, self.cell.get_temp(), self.cell.get_temp_perc(), self.cell.get_temp_color()) + + self.DischargePlot(dc) + + def __init__(self): + + self.w = WIDTH + self.h = WIDTH + BARH + + wx.Frame.__init__(self, id=-1, parent=None, name=u'EnergyMonFrame', + size=wx.Size(self.w, self.h), title=u'Energy Monitoring') + self.Bind(wx.EVT_PAINT, self.OnPaint) + self.Bind(wx.EVT_SIZE, self.OnSize) + self.Bind(wx.EVT_CLOSE, self.OnClose) + + ico = wx.Icon(PPRZ_SRC + "/sw/ground_segment/python/energy_mon/energy_mon.ico", wx.BITMAP_TYPE_ICO) + self.SetIcon(ico) + + self.bat = {} + self.temp = {} + self.cell = BatteryCell(); + + self.interface = IvyMessagesInterface("energymonframe") + self.interface.subscribe(self.message_recv) + + def OnClose(self, event): + self.interface.shutdown() + self.Destroy()