Help on custom coding for battery charging

Help on custom coding for battery charging

caner_p
Not applicable
1,182 Views
22 Replies
Message 1 of 23

Help on custom coding for battery charging

caner_p
Not applicable

[ FlexSim 19.0.0 ]

Hi all,

I hope you all are fine and healthy during this testing times.

I need help on customs coding. In v5, we have completed the battery discharging code thanks to your help. In v6, we are adding the renewable charging component to the model. I throwed in some comments and pseudo codes in custom codes in the model in the hopes of guiding you.

What needs to be done is as follows:

1) SetRenewableRate is the logic for solar energy charging. It needs to select corresponding value from the global tale RenewableRatesTable, depending on the month and hour and then define the global variable "hourlyRenewableRate". Therefore, ALL custom codes only in SetRenewableRate logic needs fixing. That is all I need.

v6.fsm

2) Code below needs to be changed so that it selects a predefined shipPVCapacity value for each ship depeding on the name of the ship. Defined the values as labels to ships, manually.

/**Custom Code*/
Object current = param(1);
treenode activity = param(2);
Token token = param(3);
Variant assignTo = param(4);
string labelName = param(5);
treenode processFlow = ownerobject(activity);

TrackedVariable battery = current.labels["Battery"];
battery.rate = dailyDischargeRate*current.dischargeRate + hourlyRenewableRate*shipPVCapacity/1000 ;

//We need to define shipPVCapacity for 4 groups depending on names of transports.
//LC1 to LC13, F1 and F3, F2 and F4, and HSC1-2
//something like this: if Model.name is "LC1" then shipPVCapacity == "750"
//These values needs to be set only once.

return battery.value/current.dischargeRate;
0 Likes
Accepted solutions (1)
1,183 Views
22 Replies
Replies (22)
Message 2 of 23

moehlmann_fe
Enthusiast
Enthusiast
Accepted solution

Since their is no counting/exlucing certain values like with the daily discharge rates, the code is actually quite simply. You just have to read the value from the table, where the current month is the row and the hour is the column (with an offset of one, because hours go from 0-23).

// Get month and hour
int month = Model.dateTime.month;
int hour = Model.dateTime.hour;
// Set rate
hourlyRenewableRate = Table("RenewableRatesTable")[month][hour+1];

Then will also want to change the delay to wait until the next full hour, instead of day.

1652339846581.png

v6(1).fsm

Message 3 of 23

caner_p
Not applicable

Thank you, Felix!


Before I open another question, I need your recommendation on how to proceed on this: I want to track how much power is charged from each dock and how many ships are charging at the same time. Then I think I will not disturb you anymore as modeling will be mostly over 🙂


There could be a better way but I think I can utilize the loc. labels for this. There are .loc labels given for each ship after it departs to the destination dock e.g. BOS_F, BOS1, BOS2, BOS3..., KSK, KSK1, KSK2, KSK3... etc. When the ship is idle at the dock, it starts charging at a preset rate but I need to see the amount of power drawn from the dock "battery" at the completion of each ship's charge (when it is not at idle anymore) and how many ships are charging at the same time at a dock. I also need the daily total charge is drawn and daily average rates for each dock "batteries".

The math is simple as we already track the battery levels for each ship, but real coding is confusing for me at this point.

There should be 4 sets of batteries: 1 for UCK_F, 1 for BOS_F, 1 for all other BOSs, and 1 for all KSKs.

The pseudocode thingy for each dock should be like this, or maybe not 🙂

set battery size for UCK_F == 20000
set battery recharge rate from the city grid for UCK_F == 1000
 
//this should record in a table that includes the ships name, how much is charged, and the duration of the charge
if ships' state == idle
record ship name
get and record the battery level on idle start
get and record the battery level on idle end
calculate and record the battery level difference
calculate and record duration
 
//charge rate control for debug
level difference divided by duration should be equal to the chargeRate of the particular dock (which is set to 4000 for UCK_F at the moment)


The daily total should just sum up the battery level differences and daily avg. rate just divides it by 24 for each day.


v7.fsm

0 Likes
Message 4 of 23

moehlmann_fe
Enthusiast
Enthusiast

You don't really need any coding for that if I understand your goal correctly. The token that sets the charge rate when the ship goes idle can create another token that stores the current time and battery level as labels.

This token then waits until a token enters the activity that sets the discharge rate. At that point you can write the info about what ship charged how much over what time and at what location to a global table with the pick option in the custom code activity.

1652368718344.pngYou can also split the writing up and add the ship, location and start time immediately. Then fill in the rest of the values later. You only have to store the number of the row that was created (Table(...).numRows).

1652368705620.png

v7_1.fsm

Message 5 of 23

caner_p
Not applicable
Thank you Felix! First off, I get lots of console errors on drawing things so that I can not properly see the model file.

From the SS above, secondly, yes this is part of what I wanted. I need it to show the start and end battery levels and the rate that it was charged.

What I mainly wanted was to set a main battery reserve for a dock and track its levels, e.g. BOS dock and any ship that recharges there needs to spend from this reserve.

0 Likes
Message 6 of 23

moehlmann_fe
Enthusiast
Enthusiast

You can add kinetic tracked variables to the docks as well and adjust their rate together with the charge rate of the ships.

I made the charging logic a bit more robust by listening to the unload event instead of the state change to idle, so it doesn't trigger every time the model is stopped.

To get a reference to the dock I take the first three characters of the 'Loc' label and search for the object with that name.

I also added a loop that adjusts the discharge rate when travelling every hour to account for the changed global PV variable.

1652428727906.png

The dock's reserves are reset in the same code block that sets the daily discharge rate.

1652428780301.png

v7-2.fsm

Message 7 of 23

caner_p
Not applicable

This looks great.

Edit: Ships batteries are still discharging while they are at idle state! This should not happen.

Edit 2: Discharging only happens while ships are travelling. When they are at any dock and they are in idle state, the battery levels should stay the same. If they are in a dock with reserve, they should start charging after completing unloading and while they are in idle.

Also Edit 2: I'll draw a diagram on how the batteries should operate. I'll update the post.

"To get a reference to the dock I take the first three characters of the 'Loc' label and search for the object with that name."

Could you please seperate reserves (and graphs) for BOS and BOS_F, and UCK and UCK_F?

Other than that, you are a master.

0 Likes
Message 8 of 23

moehlmann_fe
Enthusiast
Enthusiast

I split UCK and BOS up into two labels. Which one is changed is determined by the first letter of the task executer's name. So don't change the name of the ferries to something that doesn't with "F".

'UCK' (without "F") doesn't currently appear in the statistics because no non-ferries are using it to recharge. If I saw correctly, only very few other ships arrive there and the ones that do continue on immediately.

The discharging when idle was due to a small oversight when copying a decide activity (forgot to remove one part of the condition).

v7-3.fsm

Message 9 of 23

caner_p
Not applicable

Thank you Felix, it seems like it is working now!

Sorry for the bleeding eyes and my epic powerpoint skills. I wanted to summarise how the battery logics should work and what is needed next.

Ship battery logic:

slayt1.jpg

Dock battery logic:

slayt2.jpg

Final steps with the experimenter:

slayt3.jpg

If you need info on anything or it just doesn't make sense, please do tell.

0 Likes
Message 10 of 23

moehlmann_fe
Enthusiast
Enthusiast

One rework later, I think I got the charging/discharging as described. Each rate change is now triggered individually, including the stop when full and resume of PV when not full anymore.

For BOS and UCK it's currently built in the way that both the 'normal' and the 'F' reserve receive half the base and PV rate if both are not at capacity. If only one is charging, it receives the full rate.

The current values I put in as placeholders are too low and the reserves lose charge over multiple days.

If any of the battery/reserve levels fall below 30% the global variable 'fellBelow30' is set to 1. That way you should be able to detect invalid replications in the optimizer.

v7-4.fsm

If you need any help on the optimizer side, that should probably go into a new question. 😉

Message 11 of 23

caner_p
Not applicable

Hello again Felix. Thanks for everything you have done. However there are some misbehaving things:

i-wanna-break-free.png

- I input a ridiculously high value for dock battery grid charge rate to test it out. BOS_F reserve goes over the rated maxcapacity.

Image.png

- I know it is outdated now but Dashboard3 looks really weird. It seems like values go over the maxcapacity and it looks like there are no idle states where ships battery value is at max or at the value it entered a dock without charging (there are no horizontal lines indicating this).

And a way to adjust all maxCharge capacity and rate values from a single window would be great as a QoL improvement 🙂 Jumping from one custom code to other to change values is my current understanding of the easiest way... Maybe this should go into another question?

v7-4.fsm

0 Likes
Message 12 of 23

moehlmann_fe
Enthusiast
Enthusiast

Turns out applying rate changes individually and having the reserve value ping-pong between 'not quite full' and 'full' by constantly adding and subtracting the base rate wasn't the best idea.

Not necessarily because of the diverging charge value, but mostly because it is quite inefficient, especially in regards to collecting the statistics.

Instead the reserves now only start to deplete if the total current power draw is larger than the base rate + PV rate. If both 'not_F' and 'F' are drawing power at the same time, the base rate is distributed proportional to the drawn power for each reserve.

The statistics collector for the dashboard3 had to be updated because the activities which change the ship charge rate had changed.

Lastly, I added a table that holds the charge rates for all locations. The respective activity is reading the value corresponding to the ship's current location from it. Similarly you could write all parameters into a table and then assign those values to the respective object labels in the reset trigger of the ships and docks.

// Example to set the max reserve value on a dock
// assumes this is placed in the reset trigger
current.maxCharge = Table(...)[row][col];
current.labels["reserve"].as(TrackedVariable).value = current.maxCharge;

v7-6.fsm

Message 13 of 23

caner_p
Not applicable

Thank you. I couldn't find where "dailyDischargeRate" was in the new code effecting the discharge rate. It should be the multiplier of the battery "dischargeRate"s of all ships for that day. Can you direct me to it?

a.png

Now it seems like discharging and battery levels very similar with values of 1, 1.1 and 1.2 for dailyDischargeRate.

0 Likes
Message 14 of 23

moehlmann_fe
Enthusiast
Enthusiast

Good catch! I forgot to add that in the new activities (Adjust rate down/up).

1652551748412.png

When the discharge rate is set ('down'), the current factor is written to a label on the ship, so you can check it there.

1652551833454.png

v7-7.fsm

Message 15 of 23

caner_p
Not applicable

Could you please take a look at the SetDischargeRate logic? It always produces the same series of values for a month.

4-different-runs.png

You can even disregard the "maximum days for x value" feature. If there are 5 of 1.2 values in a month, by 0.03 chance, so be it 🙂

Please use this file: v8_BASE_CONSUMPTION_trial.fsm

0 Likes
Message 16 of 23

moehlmann_fe
Enthusiast
Enthusiast

To get different results between model runs, you have to deactivate the 'Repeat Random Streams' option.

1652682298059.png

Message 17 of 23

caner_p
Not applicable
Thank you!
0 Likes
Message 18 of 23

caner_p
Not applicable

Hi again, @Felix Möhlmann. I hope your health is good and having a good day. Again, there is one last time I'm in need of your help and guidance. Dock batteries sometimes misbehave.


-They tend to overcharge:

dock-battery-overcharge-problem.png

-They tend to recharge when no ship is charging (e.g. at night):

there-is-no-such-recharge-happening.png


v9_Final.fsm

Can you please help?

0 Likes
Message 19 of 23

moehlmann_fe
Enthusiast
Enthusiast

The smaller peaks you are seeing in the first screenshot are graphical artifacts that happen when there are points that form a triangle are very close together on the x-axis. The actul data point is at the cap but the line sort of 'overshoots' because the triangle that forms the peak ends in a very acute angle.

1652979079535.png

These peaks will appear/disappear when the interval that the graph displays changes. You can set the graph to use the 'time window' on the x-axis and play with the interval to see this effect.

visualartifact.gif

The larger rise above the max capacity and the recharging at night were seemingly caused by a floating point error, where 'reserve < maxCapacity' is evaluated as true.

I changed those checks to 'reserve < maxCapacity - 0.001' to prevent this.

v9-final-fm.fsm

0 Likes
Message 20 of 23

caner_p
Not applicable

Hi there Felix. I hope you had a lovely weekend. I know that I did not give you any rest, so please accept my apologies.

The "SetDischargeRate" logic is not randomly generating the "dischargeFactor" value. In fact, it always produces the same series. Please see the results for 1 month period.


Col 1Col 1Col 1Col 1
1111
1,11,11,11,1
1111
1111
1,11,11,11,1
1111
1111
1111
1111
1111
1,11,11,11,1
1111
1,11,11,11,1
1,11,11,11,1
1111
1111
1,11,11,11,1
1111
1111
1111
1,11,11,11,1
1,11,11,11,1
1111
1,11,11,11,1
1111
1,11,11,11,1
1,11,11,11,1
1111
1111
1,11,11,11,1
1,11,11,11,1
1,11,11,11,1
1111
1111
1,21,21,21,2


Could you please alter the custom code so that it really randomizes?

If you want, you can use the ratio and probability table below (For January, there is 0.55 probability for dischargeFactor to be 1 for that day, 0.42 probability for dischargeFactor to be 1.1 for that day and 0.03 probability for dischargeFactor to be 1.2 for that day):

10,551,10,421,20,03
10,391,10,481,20,03
10,391,10,581,20,03
10,351,10,581,20,03
10,231,10,741,20,03
10,061,10,811,20,1
10,031,10,741,20,23
10,061,10,811,20,13
10,161,10,741,20,06
10,481,10,481,20,03
10,581,10,391,20
10,551,10,421,20,03


For example, it does not matter if there are 3 consecutive days with 1.2 value or not. It is just chance. However, it just cannot have the exact same series the next time it runs.

Please use this file: v8_BASE_CONSUMPTION_trial.fsm

0 Likes