by hjsmuc » Sat Jul 15, 2023 6:27 am
Here is what ChatGPT managed to do after some heated discussion, give it a try. Happy to hear what you think and please point out bugs or omissions.
import os
import math
from math import radians, degrees, sin, cos, atan2, sqrt
def dead_reckoning(lat, lon, course, speed, hours, wind_speed, wind_direction, current_speed, current_direction):
# Convert course, wind direction, and current direction to radians
course_rad = math.radians(course)
wind_direction_rad = math.radians(wind_direction)
current_direction_rad = math.radians(current_direction)
# Convert speed from knots to nautical miles per hour
speed_nm = speed * 1
# Calculate distance traveled in nautical miles
distance_nm = speed_nm * hours
# Calculate the components of the wind vector
wind_speed_x = wind_speed * math.cos(wind_direction_rad)
wind_speed_y = wind_speed * math.sin(wind_direction_rad)
# Calculate the components of the current vector
current_speed_x = current_speed * math.cos(current_direction_rad)
current_speed_y = current_speed * math.sin(current_direction_rad)
# Calculate the components of the resulting vector
result_speed_x = speed_nm * math.cos(course_rad) + wind_speed_x + current_speed_x
result_speed_y = speed_nm * math.sin(course_rad) + wind_speed_y + current_speed_y
# Calculate the resulting speed and course
result_speed = math.sqrt(result_speed_x ** 2 + result_speed_y ** 2)
result_course = math.degrees(math.atan2(result_speed_y, result_speed_x))
# Convert the resulting course to the range of 0-360 degrees
result_course = (result_course + 360) % 360
# Calculate change in latitude and longitude
delta_lat = (distance_nm / 60.0) * math.cos(math.radians(result_course))
delta_lon = (distance_nm / 60.0) * math.sin(math.radians(result_course))
# Calculate new latitude and longitude
new_lat = lat + delta_lat
new_lon = lon + delta_lon
return new_lat, new_lon
def format_coordinate(coordinate, is_longitude):
if is_longitude:
direction = "W" if coordinate < 0 else "E"
else:
direction = "S" if coordinate < 0 else "N"
return abs(coordinate), direction
def read_waypoints(situation_file_path):
waypoints = []
found_start = False
with open(situation_file_path, "r") as f:
lines = f.readlines()
waypoint_counter = 0
for line in lines:
line = line.strip()
if "1" in line and "[vehicle_own]" in line:
found_start = True
continue
if "1" in line and "[vehicle_next_position]" in line:
break
if found_start and line.endswith("[vehicle_waypoint]"):
waypoint_parts = line.split("\t")
if len(waypoint_parts) >= 2:
waypoint_counter += 1
longitude = -float(waypoint_parts[0]) # Negative values indicate West
latitude = float(waypoint_parts[1])
formatted_longitude, longitude_direction = format_coordinate(longitude, is_longitude=True)
formatted_latitude, latitude_direction = format_coordinate(latitude, is_longitude=False)
waypoint = (
chr(ord('A') + waypoint_counter - 1), formatted_longitude, longitude_direction,
formatted_latitude, latitude_direction
)
waypoints.append(waypoint)
return waypoints
def calculate_course_to_waypoint(ship_longitude, ship_latitude, ship_speed, waypoints):
waypoint_name = input("Enter the name of the waypoint: ")
waypoint = None
for wp in waypoints:
if wp[0] == waypoint_name:
waypoint = wp
break
if waypoint is None:
print("Waypoint not found.")
return
waypoint_longitude = waypoint[1]
waypoint_latitude = waypoint[3]
# Confirm the speed from the file
confirm_speed = input(f"Current speed from file: {ship_speed} nm. Is this speed correct? (yes/no): ")
if confirm_speed.lower() in ["no", "n"]:
new_speed = float(input("Enter the new speed in nm: "))
ship_speed = new_speed
dlon = radians(waypoint_longitude) - radians(ship_longitude)
lat1 = radians(ship_latitude)
lat2 = radians(waypoint_latitude)
y = sin(dlon) * cos(lat2)
x = cos(lat1) * sin(lat2) - sin(lat1) * cos(lat2) * cos(dlon)
initial_bearing = atan2(y, x)
initial_bearing = (degrees(initial_bearing) + 360) % 360
distance = calculate_distance(ship_latitude, ship_longitude, waypoint_latitude, waypoint_longitude)
time = distance / ship_speed
print(f"Course to waypoint {waypoint_name}: {initial_bearing:.2f}\u00b0")
print(f"Distance to waypoint {waypoint_name}: {distance:.2f} nm")
print(f"Time to reach waypoint {waypoint_name}: {time:.2f} hours")
def calculate_course_between_waypoints(ship_longitude, ship_latitude, ship_speed, waypoints):
waypoint1_name = input("Enter the name of the first waypoint: ")
waypoint2_name = input("Enter the name of the second waypoint: ")
waypoint1 = None
waypoint2 = None
for wp in waypoints:
if wp[0] == waypoint1_name:
waypoint1 = wp
if wp[0] == waypoint2_name:
waypoint2 = wp
if waypoint1 is None or waypoint2 is None:
print("One or both waypoints not found.")
return
waypoint1_longitude = waypoint1[1]
waypoint1_latitude = waypoint1[3]
waypoint2_longitude = waypoint2[1]
waypoint2_latitude = waypoint2[3]
# Confirm the speed from the file
confirm_speed = input(f"Current speed from file: {ship_speed} nm. Is this speed correct? (yes/no): ")
if confirm_speed.lower() in ["no", "n"]:
new_speed = float(input("Enter the new speed in nm: "))
ship_speed = new_speed
dlon = radians(waypoint2_longitude) - radians(waypoint1_longitude)
lat1 = radians(waypoint1_latitude)
lat2 = radians(waypoint2_latitude)
y = sin(dlon) * cos(lat2)
x = cos(lat1) * sin(lat2) - sin(lat1) * cos(lat2) * cos(dlon)
initial_bearing = atan2(y, x)
initial_bearing = (degrees(initial_bearing) + 360) % 360
distance = calculate_distance(waypoint1_latitude, waypoint1_longitude, waypoint2_latitude, waypoint2_longitude)
time = distance / ship_speed
print(f"Course between waypoints {waypoint1_name} and {waypoint2_name}: {initial_bearing:.2f}\u00b0")
print(f"Distance between waypoints {waypoint1_name} and {waypoint2_name}: {distance:.2f} nm")
print(f"Time to travel between waypoints {waypoint1_name} and {waypoint2_name}: {time:.2f} hours")
def calculate_distance(lat1, lon1, lat2, lon2):
R = 6371 # Radius of the Earth in km
dlat = radians(lat2 - lat1)
dlon = radians(lon2 - lon1)
a = sin(dlat / 2) * sin(dlat / 2) + cos(radians(lat1)) * cos(radians(lat2)) * sin(dlon / 2) * sin(dlon / 2)
c = 2 * atan2(sqrt(a), sqrt(1 - a))
distance = R * c
# Convert distance from kilometers to nautical miles
distance_nm = distance / 1.852
return distance_nm
def calculate_course_to_all_waypoints(ship_longitude, ship_latitude, ship_speed, waypoints):
start_waypoint = input("Enter the name of the first waypoint: ")
start_index = None
for i, waypoint in enumerate(waypoints):
if waypoint[0] == start_waypoint:
start_index = i
break
if start_index is None:
print("Start waypoint not found.")
return
# Confirm the speed from the file
confirm_speed = input(f"Current speed from file: {ship_speed} nm. Is this speed correct? (yes/no): ")
if confirm_speed.lower() in ["no", "n"]:
new_speed = float(input("Enter the new speed in nm: "))
ship_speed = new_speed
total_distance = 0
total_time = 0
for i in range(start_index, len(waypoints) - 1):
current_waypoint = waypoints
next_waypoint = waypoints[i + 1]
current_longitude = current_waypoint[1]
current_latitude = current_waypoint[3]
next_longitude = next_waypoint[1]
next_latitude = next_waypoint[3]
dlon = radians(next_longitude) - radians(current_longitude)
lat1 = radians(current_latitude)
lat2 = radians(next_latitude)
y = sin(dlon) * cos(lat2)
x = cos(lat1) * sin(lat2) - sin(lat1) * cos(lat2) * cos(dlon)
initial_bearing = atan2(y, x)
initial_bearing = (degrees(initial_bearing) + 360) % 360
distance = calculate_distance(current_latitude, current_longitude, next_latitude, next_longitude)
time = distance / ship_speed
total_distance += distance
total_time += time
print(f"Course from {current_waypoint[0]} to {next_waypoint[0]}: {initial_bearing:.2f}\u00b0")
print(f"Distance from {current_waypoint[0]} to {next_waypoint[0]}: {distance:.2f} nm")
print(f"Time to travel from {current_waypoint[0]} to {next_waypoint[0]}: {time:.2f} hours")
print(f"Total Distance: {total_distance:.2f} nm")
print(f"Total Time: {total_time:.2f} hours")
def calculate_new_position(ship_longitude, ship_latitude, ship_speed, data, situation_file_path):
print("Option 4: Calculate a new position")
# Prompt user for speed confirmation
confirm_speed = input(f"Current speed from file: {ship_speed} nm. Is this speed correct? (yes/no): ")
if confirm_speed.lower() in ["no", "n"]:
ship_speed = float(input("Enter the new speed in nm: "))
# Prompt user for course confirmation
course_from_file = float(data["vehicle_beta"])
if course_from_file >= 0:
calculated_course = round(course_from_file / 0.0174444, 2)
else:
calculated_course = round((course_from_file / 0.0174444) + 360, 2)
confirm_course = input(f"Current course from file: {calculated_course}°. Is this course correct? (yes/no): ")
if confirm_course.lower() in ["no", "n"]:
ship_course = float(input("Enter the new course in degrees: "))
else:
ship_course = calculated_course
# Prompt user for wind speed, wind direction, current speed, current direction, and travel time
wind_speed = float(input("Enter the wind speed in nm: "))
wind_direction = float(input("Enter the wind direction in degrees: "))
current_speed = float(input("Enter the current speed in nm: "))
current_direction = float(input("Enter the current direction in degrees: "))
travel_time = float(input("Enter the travel time in hours: "))
# Calculate new position using dead reckoning
new_lat, new_lon = dead_reckoning(ship_latitude, ship_longitude, ship_course, ship_speed, travel_time,
wind_speed, wind_direction, current_speed, current_direction)
# Format longitude and latitude with directions
lon_direction = "E" if new_lon >= 0 else "W"
lat_direction = "N" if new_lat >= 0 else "S"
print("New Position Calculation:")
print(f"Initial Position: Longitude: {abs(ship_longitude):.6f}\u00b0{lon_direction}, Latitude: {abs(ship_latitude):.6f}\u00b0{lat_direction}")
print(f"Final Position: Longitude: {abs(new_lon):.6f}\u00b0{lon_direction}, Latitude: {abs(new_lat):.6f}\u00b0{lat_direction}")
# Update the latitude and longitude in the data dictionary
data["vehicle_east"] = str(new_lon)
data["vehicle_north"] = str(new_lat)
# Prompt user to write new position to situation file
write_to_file = input("Do you want to write the new position to the situation file? (yes/no): ")
if write_to_file.lower() in ["yes", "y"]:
# Write the updated data back to the situation file
with open(situation_file_path, "r") as f:
lines = f.readlines()
with open(situation_file_path, "w") as f:
for line in lines:
if line.strip().endswith("[vehicle_east]"):
f.write(f"{new_lon:.6f}\t[vehicle_east]\n")
elif line.strip().endswith("[vehicle_north]"):
f.write(f"{new_lat:.6f}\t[vehicle_north]\n")
else:
f.write(line)
print("New position written to the situation file.")
else:
print("New position not written to the situation file.")
# Prompt user to delete waypoints from situation file
delete_waypoints = input("Do you want to delete the waypoints from the situation file? (yes/no): ")
if delete_waypoints.lower() in ["yes", "y"]:
with open(situation_file_path, "r") as f:
lines = f.readlines()
start_deleting = False
with open(situation_file_path, "w") as f:
for line in lines:
if line.strip().endswith("[vehicle_own]"):
start_deleting = True
elif line.strip().endswith("[vehicle_next_waypoint]"):
start_deleting = False
if not start_deleting or line.strip().endswith("[vehicle_own]"):
f.write(line)
print("Waypoints deleted from the situation file if requested.")
def main():
situation_file = input("Enter the name of the situation file (without .txt extension): ")
situation_file += ".txt"
situation_file_path = os.path.join("G:\\", "Virtual Sailor", "situations", situation_file)
data = {}
with open(situation_file_path, "r") as f:
for line in f:
line = line.strip()
if not line or line.startswith("//") or line.startswith("@"):
continue
parts = line.split("\t")
key = parts[-1].strip("[]")
value = parts[:-1]
if len(value) == 1:
value = value[0]
data[key] = value
ship_longitude = float(data["vehicle_east"])
lon_direction = "E" if ship_longitude >= 0 else "W"
print(f"Longitude: {abs(ship_longitude):.6f}\u00b0{lon_direction}")
ship_latitude = float(data["vehicle_north"])
lat_direction = "N" if ship_latitude >= 0 else "S"
print(f"Latitude: {abs(ship_latitude):.6f}\u00b0{lat_direction}")
ship_speed = float(data["vehicle_speed"]) * 2
print(f"Speed: {ship_speed} nm")
course = float(data["vehicle_beta"])
if course >= 0:
course = course / 0.0174444
else:
course = (course / 0.0174444) + 360
print(f"Course: {course:.2f}\u00b0")
waypoints = read_waypoints(situation_file_path)
if waypoints:
print("Waypoint positions:")
for waypoint in waypoints:
name, longitude, longitude_direction, latitude, latitude_direction = waypoint
print(
f"Waypoint {name}: Longitude: {longitude:.6f}\u00b0{longitude_direction}, Latitude: {latitude:.6f}\u00b0{latitude_direction}"
)
else:
print("No waypoints found.")
while True:
calculate_navigation = input("Do you want to perform navigation calculations? (yes/no): ")
if calculate_navigation.lower() in ["no", "n"]:
break
elif calculate_navigation.lower() in ["yes", "y"]:
print("Navigation Calculations Menu:")
print("1. Calculate course and time to a waypoint")
print("2. Calculate course and distance between two waypoints")
print("3. Calculate course and speed for all waypoints")
print("4. Calculate a new position")
option = input("Enter the option number (1-4): ")
if option == "1":
calculate_course_to_waypoint(ship_longitude, ship_latitude, ship_speed, waypoints)
elif option == "2":
calculate_course_between_waypoints(ship_longitude, ship_latitude, ship_speed, waypoints)
elif option == "3":
calculate_course_to_all_waypoints(ship_longitude, ship_latitude, ship_speed, waypoints)
elif option == "4":
calculate_new_position(ship_longitude, ship_latitude, ship_speed, data, situation_file_path)
else:
print("Invalid option.")
else:
print("Invalid input. Please enter 'yes', 'no', 'y', or 'n'.")
if __name__ == "__main__":
main()
Here is what ChatGPT managed to do after some heated discussion, give it a try. Happy to hear what you think and please point out bugs or omissions.
import os
import math
from math import radians, degrees, sin, cos, atan2, sqrt
def dead_reckoning(lat, lon, course, speed, hours, wind_speed, wind_direction, current_speed, current_direction):
# Convert course, wind direction, and current direction to radians
course_rad = math.radians(course)
wind_direction_rad = math.radians(wind_direction)
current_direction_rad = math.radians(current_direction)
# Convert speed from knots to nautical miles per hour
speed_nm = speed * 1
# Calculate distance traveled in nautical miles
distance_nm = speed_nm * hours
# Calculate the components of the wind vector
wind_speed_x = wind_speed * math.cos(wind_direction_rad)
wind_speed_y = wind_speed * math.sin(wind_direction_rad)
# Calculate the components of the current vector
current_speed_x = current_speed * math.cos(current_direction_rad)
current_speed_y = current_speed * math.sin(current_direction_rad)
# Calculate the components of the resulting vector
result_speed_x = speed_nm * math.cos(course_rad) + wind_speed_x + current_speed_x
result_speed_y = speed_nm * math.sin(course_rad) + wind_speed_y + current_speed_y
# Calculate the resulting speed and course
result_speed = math.sqrt(result_speed_x ** 2 + result_speed_y ** 2)
result_course = math.degrees(math.atan2(result_speed_y, result_speed_x))
# Convert the resulting course to the range of 0-360 degrees
result_course = (result_course + 360) % 360
# Calculate change in latitude and longitude
delta_lat = (distance_nm / 60.0) * math.cos(math.radians(result_course))
delta_lon = (distance_nm / 60.0) * math.sin(math.radians(result_course))
# Calculate new latitude and longitude
new_lat = lat + delta_lat
new_lon = lon + delta_lon
return new_lat, new_lon
def format_coordinate(coordinate, is_longitude):
if is_longitude:
direction = "W" if coordinate < 0 else "E"
else:
direction = "S" if coordinate < 0 else "N"
return abs(coordinate), direction
def read_waypoints(situation_file_path):
waypoints = []
found_start = False
with open(situation_file_path, "r") as f:
lines = f.readlines()
waypoint_counter = 0
for line in lines:
line = line.strip()
if "1" in line and "[vehicle_own]" in line:
found_start = True
continue
if "1" in line and "[vehicle_next_position]" in line:
break
if found_start and line.endswith("[vehicle_waypoint]"):
waypoint_parts = line.split("\t")
if len(waypoint_parts) >= 2:
waypoint_counter += 1
longitude = -float(waypoint_parts[0]) # Negative values indicate West
latitude = float(waypoint_parts[1])
formatted_longitude, longitude_direction = format_coordinate(longitude, is_longitude=True)
formatted_latitude, latitude_direction = format_coordinate(latitude, is_longitude=False)
waypoint = (
chr(ord('A') + waypoint_counter - 1), formatted_longitude, longitude_direction,
formatted_latitude, latitude_direction
)
waypoints.append(waypoint)
return waypoints
def calculate_course_to_waypoint(ship_longitude, ship_latitude, ship_speed, waypoints):
waypoint_name = input("Enter the name of the waypoint: ")
waypoint = None
for wp in waypoints:
if wp[0] == waypoint_name:
waypoint = wp
break
if waypoint is None:
print("Waypoint not found.")
return
waypoint_longitude = waypoint[1]
waypoint_latitude = waypoint[3]
# Confirm the speed from the file
confirm_speed = input(f"Current speed from file: {ship_speed} nm. Is this speed correct? (yes/no): ")
if confirm_speed.lower() in ["no", "n"]:
new_speed = float(input("Enter the new speed in nm: "))
ship_speed = new_speed
dlon = radians(waypoint_longitude) - radians(ship_longitude)
lat1 = radians(ship_latitude)
lat2 = radians(waypoint_latitude)
y = sin(dlon) * cos(lat2)
x = cos(lat1) * sin(lat2) - sin(lat1) * cos(lat2) * cos(dlon)
initial_bearing = atan2(y, x)
initial_bearing = (degrees(initial_bearing) + 360) % 360
distance = calculate_distance(ship_latitude, ship_longitude, waypoint_latitude, waypoint_longitude)
time = distance / ship_speed
print(f"Course to waypoint {waypoint_name}: {initial_bearing:.2f}\u00b0")
print(f"Distance to waypoint {waypoint_name}: {distance:.2f} nm")
print(f"Time to reach waypoint {waypoint_name}: {time:.2f} hours")
def calculate_course_between_waypoints(ship_longitude, ship_latitude, ship_speed, waypoints):
waypoint1_name = input("Enter the name of the first waypoint: ")
waypoint2_name = input("Enter the name of the second waypoint: ")
waypoint1 = None
waypoint2 = None
for wp in waypoints:
if wp[0] == waypoint1_name:
waypoint1 = wp
if wp[0] == waypoint2_name:
waypoint2 = wp
if waypoint1 is None or waypoint2 is None:
print("One or both waypoints not found.")
return
waypoint1_longitude = waypoint1[1]
waypoint1_latitude = waypoint1[3]
waypoint2_longitude = waypoint2[1]
waypoint2_latitude = waypoint2[3]
# Confirm the speed from the file
confirm_speed = input(f"Current speed from file: {ship_speed} nm. Is this speed correct? (yes/no): ")
if confirm_speed.lower() in ["no", "n"]:
new_speed = float(input("Enter the new speed in nm: "))
ship_speed = new_speed
dlon = radians(waypoint2_longitude) - radians(waypoint1_longitude)
lat1 = radians(waypoint1_latitude)
lat2 = radians(waypoint2_latitude)
y = sin(dlon) * cos(lat2)
x = cos(lat1) * sin(lat2) - sin(lat1) * cos(lat2) * cos(dlon)
initial_bearing = atan2(y, x)
initial_bearing = (degrees(initial_bearing) + 360) % 360
distance = calculate_distance(waypoint1_latitude, waypoint1_longitude, waypoint2_latitude, waypoint2_longitude)
time = distance / ship_speed
print(f"Course between waypoints {waypoint1_name} and {waypoint2_name}: {initial_bearing:.2f}\u00b0")
print(f"Distance between waypoints {waypoint1_name} and {waypoint2_name}: {distance:.2f} nm")
print(f"Time to travel between waypoints {waypoint1_name} and {waypoint2_name}: {time:.2f} hours")
def calculate_distance(lat1, lon1, lat2, lon2):
R = 6371 # Radius of the Earth in km
dlat = radians(lat2 - lat1)
dlon = radians(lon2 - lon1)
a = sin(dlat / 2) * sin(dlat / 2) + cos(radians(lat1)) * cos(radians(lat2)) * sin(dlon / 2) * sin(dlon / 2)
c = 2 * atan2(sqrt(a), sqrt(1 - a))
distance = R * c
# Convert distance from kilometers to nautical miles
distance_nm = distance / 1.852
return distance_nm
def calculate_course_to_all_waypoints(ship_longitude, ship_latitude, ship_speed, waypoints):
start_waypoint = input("Enter the name of the first waypoint: ")
start_index = None
for i, waypoint in enumerate(waypoints):
if waypoint[0] == start_waypoint:
start_index = i
break
if start_index is None:
print("Start waypoint not found.")
return
# Confirm the speed from the file
confirm_speed = input(f"Current speed from file: {ship_speed} nm. Is this speed correct? (yes/no): ")
if confirm_speed.lower() in ["no", "n"]:
new_speed = float(input("Enter the new speed in nm: "))
ship_speed = new_speed
total_distance = 0
total_time = 0
for i in range(start_index, len(waypoints) - 1):
current_waypoint = waypoints[i]
next_waypoint = waypoints[i + 1]
current_longitude = current_waypoint[1]
current_latitude = current_waypoint[3]
next_longitude = next_waypoint[1]
next_latitude = next_waypoint[3]
dlon = radians(next_longitude) - radians(current_longitude)
lat1 = radians(current_latitude)
lat2 = radians(next_latitude)
y = sin(dlon) * cos(lat2)
x = cos(lat1) * sin(lat2) - sin(lat1) * cos(lat2) * cos(dlon)
initial_bearing = atan2(y, x)
initial_bearing = (degrees(initial_bearing) + 360) % 360
distance = calculate_distance(current_latitude, current_longitude, next_latitude, next_longitude)
time = distance / ship_speed
total_distance += distance
total_time += time
print(f"Course from {current_waypoint[0]} to {next_waypoint[0]}: {initial_bearing:.2f}\u00b0")
print(f"Distance from {current_waypoint[0]} to {next_waypoint[0]}: {distance:.2f} nm")
print(f"Time to travel from {current_waypoint[0]} to {next_waypoint[0]}: {time:.2f} hours")
print(f"Total Distance: {total_distance:.2f} nm")
print(f"Total Time: {total_time:.2f} hours")
def calculate_new_position(ship_longitude, ship_latitude, ship_speed, data, situation_file_path):
print("Option 4: Calculate a new position")
# Prompt user for speed confirmation
confirm_speed = input(f"Current speed from file: {ship_speed} nm. Is this speed correct? (yes/no): ")
if confirm_speed.lower() in ["no", "n"]:
ship_speed = float(input("Enter the new speed in nm: "))
# Prompt user for course confirmation
course_from_file = float(data["vehicle_beta"])
if course_from_file >= 0:
calculated_course = round(course_from_file / 0.0174444, 2)
else:
calculated_course = round((course_from_file / 0.0174444) + 360, 2)
confirm_course = input(f"Current course from file: {calculated_course}°. Is this course correct? (yes/no): ")
if confirm_course.lower() in ["no", "n"]:
ship_course = float(input("Enter the new course in degrees: "))
else:
ship_course = calculated_course
# Prompt user for wind speed, wind direction, current speed, current direction, and travel time
wind_speed = float(input("Enter the wind speed in nm: "))
wind_direction = float(input("Enter the wind direction in degrees: "))
current_speed = float(input("Enter the current speed in nm: "))
current_direction = float(input("Enter the current direction in degrees: "))
travel_time = float(input("Enter the travel time in hours: "))
# Calculate new position using dead reckoning
new_lat, new_lon = dead_reckoning(ship_latitude, ship_longitude, ship_course, ship_speed, travel_time,
wind_speed, wind_direction, current_speed, current_direction)
# Format longitude and latitude with directions
lon_direction = "E" if new_lon >= 0 else "W"
lat_direction = "N" if new_lat >= 0 else "S"
print("New Position Calculation:")
print(f"Initial Position: Longitude: {abs(ship_longitude):.6f}\u00b0{lon_direction}, Latitude: {abs(ship_latitude):.6f}\u00b0{lat_direction}")
print(f"Final Position: Longitude: {abs(new_lon):.6f}\u00b0{lon_direction}, Latitude: {abs(new_lat):.6f}\u00b0{lat_direction}")
# Update the latitude and longitude in the data dictionary
data["vehicle_east"] = str(new_lon)
data["vehicle_north"] = str(new_lat)
# Prompt user to write new position to situation file
write_to_file = input("Do you want to write the new position to the situation file? (yes/no): ")
if write_to_file.lower() in ["yes", "y"]:
# Write the updated data back to the situation file
with open(situation_file_path, "r") as f:
lines = f.readlines()
with open(situation_file_path, "w") as f:
for line in lines:
if line.strip().endswith("[vehicle_east]"):
f.write(f"{new_lon:.6f}\t[vehicle_east]\n")
elif line.strip().endswith("[vehicle_north]"):
f.write(f"{new_lat:.6f}\t[vehicle_north]\n")
else:
f.write(line)
print("New position written to the situation file.")
else:
print("New position not written to the situation file.")
# Prompt user to delete waypoints from situation file
delete_waypoints = input("Do you want to delete the waypoints from the situation file? (yes/no): ")
if delete_waypoints.lower() in ["yes", "y"]:
with open(situation_file_path, "r") as f:
lines = f.readlines()
start_deleting = False
with open(situation_file_path, "w") as f:
for line in lines:
if line.strip().endswith("[vehicle_own]"):
start_deleting = True
elif line.strip().endswith("[vehicle_next_waypoint]"):
start_deleting = False
if not start_deleting or line.strip().endswith("[vehicle_own]"):
f.write(line)
print("Waypoints deleted from the situation file if requested.")
def main():
situation_file = input("Enter the name of the situation file (without .txt extension): ")
situation_file += ".txt"
situation_file_path = os.path.join("G:\\", "Virtual Sailor", "situations", situation_file)
data = {}
with open(situation_file_path, "r") as f:
for line in f:
line = line.strip()
if not line or line.startswith("//") or line.startswith("@"):
continue
parts = line.split("\t")
key = parts[-1].strip("[]")
value = parts[:-1]
if len(value) == 1:
value = value[0]
data[key] = value
ship_longitude = float(data["vehicle_east"])
lon_direction = "E" if ship_longitude >= 0 else "W"
print(f"Longitude: {abs(ship_longitude):.6f}\u00b0{lon_direction}")
ship_latitude = float(data["vehicle_north"])
lat_direction = "N" if ship_latitude >= 0 else "S"
print(f"Latitude: {abs(ship_latitude):.6f}\u00b0{lat_direction}")
ship_speed = float(data["vehicle_speed"]) * 2
print(f"Speed: {ship_speed} nm")
course = float(data["vehicle_beta"])
if course >= 0:
course = course / 0.0174444
else:
course = (course / 0.0174444) + 360
print(f"Course: {course:.2f}\u00b0")
waypoints = read_waypoints(situation_file_path)
if waypoints:
print("Waypoint positions:")
for waypoint in waypoints:
name, longitude, longitude_direction, latitude, latitude_direction = waypoint
print(
f"Waypoint {name}: Longitude: {longitude:.6f}\u00b0{longitude_direction}, Latitude: {latitude:.6f}\u00b0{latitude_direction}"
)
else:
print("No waypoints found.")
while True:
calculate_navigation = input("Do you want to perform navigation calculations? (yes/no): ")
if calculate_navigation.lower() in ["no", "n"]:
break
elif calculate_navigation.lower() in ["yes", "y"]:
print("Navigation Calculations Menu:")
print("1. Calculate course and time to a waypoint")
print("2. Calculate course and distance between two waypoints")
print("3. Calculate course and speed for all waypoints")
print("4. Calculate a new position")
option = input("Enter the option number (1-4): ")
if option == "1":
calculate_course_to_waypoint(ship_longitude, ship_latitude, ship_speed, waypoints)
elif option == "2":
calculate_course_between_waypoints(ship_longitude, ship_latitude, ship_speed, waypoints)
elif option == "3":
calculate_course_to_all_waypoints(ship_longitude, ship_latitude, ship_speed, waypoints)
elif option == "4":
calculate_new_position(ship_longitude, ship_latitude, ship_speed, data, situation_file_path)
else:
print("Invalid option.")
else:
print("Invalid input. Please enter 'yes', 'no', 'y', or 'n'.")
if __name__ == "__main__":
main()