Conversation
|
@G0rocks I can see the use of this if it is made general. By that, I mean it should write the result of the VPP to the CSV format, which is normally used in routing software. The current version is too specific for your use case, but it is a special case of the more general polar csv format. I also don't understand why you average the boat speed. You get multiple boat speeds, but there is only one that is the best; you should just use the max boat speed at that TWA/TWS point. |
|
The reason for averaging the boat speed is that I did not know which one was the correct one so I thought to myself that if I averaged them I'd probably get something close to the realistic one. Regarding the generalization, can you tell me explicitly what needs to change so that this function fulfills your requirement of writing the result of the VPP to the CSV format? I don't know how you want this done even though I am probably up for fixing it as long as it still fulfills my requirement of being compatible with OpenCPN. Note that currently OpenCPN polars only work in 5° increments (or multiples of 5°) and when it comes to the wind speed they work in increments of 2 (or multiples of 2) regardless of if it is in knots or meters/sec or another unit but the OpenCPN plugin always writes "knots". |
|
Okay, I can guide you on how to select the best boat speed later. Ideally, we want the function to do something like this (pseudo-code) def write_CSV(VPP, save, fname="SailChart.png"):
tws = VPP.tws_range
twa = VPP.twa_range
# generate header for csv file
writer = csv.writer(file, delimiter=";")
# Write header with TWS in knots
writer.writerow((hcat(["TWA\TWS", [str(ws) for ws in tws]]))
# Loop through every degree
for angle in twa:
row = make_row_from_store(VPP.store)
writer.writerow(row)And then in your VPP setup, you need to set the correct analysis vpp.set_analysis(
tws_range=np.arange(2.0, 40.0, 2.0), twa_range=np.arrange(0.0, 181.0, 5.0)
)which will result in the TWS and TWA you want. But if a user decides he wants to write a CSV file with only |
|
@G0rocks I've written the function quickly. If you don't specify the def csv_write(VPP, tws_range=None, twa_range=None, fname="polar.csv"):
if not hasattr(VPP, "store"):
raise ValueError("VPP object must have a 'store' attribute to use to export to csv.")
import csv
# if we specify tws_range and twa_range, we use them, otherwise we use the ones from VPP
tws = VPP.tws_range if tws_range is None else tws_range
twa = VPP.twa_range if twa_range is None else twa_range
store = np.max(VPP.store[:, :, :, 0], axis=2)/KNOTS_TO_MPS
# if we specify a custom TWA or TWS range, we make a custom structure and we interpolate the results in it
if tws_range is not None or twa_range is not None:
func = RectBivariateSpline(VPP.tws_range, VPP.twa_range, store)
store = func(tws, twa)
with open(fname, mode="w", newline="") as file:
# generate header for csv file
writer = csv.writer(file, delimiter=";")
# Write header with TWS in knots
writer.writerow(["TWA\TWS"] + [str(round(ws/KNOTS_TO_MPS, 2)) for ws in tws])
# Loop through every degree
for j, angle in enumerate(twa):
row = [str(angle)] + [str(round(store[i, j], 2)) for i in range(len(tws))]
writer.writerow(row)If it roughly tests and it works. # standard write of the results
csv_write(vpp, fname="polar.csv")
# custom twa range
csv_write(vpp, twa_range=np.linspace(30.0, 180.0, 16), fname="polar.csv")
# custom tws and tws range
csv_write(vpp, twa_range=np.linspace(30.0, 180.0, 10),
tws_range=np.linspace(4.0, 22.0, 10), fname="polar.csv")I'll let you test it and update the PR if that works for you. I cannot checkout your PR and implement it myself |
| with open(fname, mode="w", newline="") as file: | ||
| writer = csv.writer(file, delimiter=";") | ||
| # Write header with TWS in knots | ||
| writer.writerow(["TWA\TWS", "2", "4", "6", "8", "10", "12", "14", "16", "18", "20", "22", "24", "26", "28", "30", "32", "34", "36", "38", "40"]) |
There was a problem hiding this comment.
This is not general, it should use the tws_range array to generate the header of the CSV, then in your specific case, you can make sure you run these TWS.
| # Write header with TWS in knots | ||
| writer.writerow(["TWA\TWS", "2", "4", "6", "8", "10", "12", "14", "16", "18", "20", "22", "24", "26", "28", "30", "32", "34", "36", "38", "40"]) | ||
| # Loop through every degree from 0°to 180° in 5° increments | ||
| for angle in range(0, 181, 5): |
There was a problem hiding this comment.
again, not general, use the twa_range
| row = [None] * 21 | ||
| # Set angle | ||
| row[0] = angle | ||
| # Go through each TWS and get the corresponding boat speed for the current angle |
There was a problem hiding this comment.
if you the tws_range and twa_range you don't need to do all this, You can just go through the store array and take the value there.
Fixes #45