Guest User

sailboat_navigation_algorithm_v1

a guest
Nov 21st, 2025
28
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.75 KB | None | 0 0
  1. import math
  2. import matplotlib.pyplot as plt
  3.  
  4. class Boat:
  5. def __init__(self, boat_x=0.0, boat_y=0.0, heading_angle=0.0, goal_x=100.0, goal_y=100.0):
  6. self.boat_x = boat_x
  7. self.boat_y = boat_y
  8. self.heading_angle = heading_angle
  9. self.goal_x = goal_x
  10. self.goal_y = goal_y
  11.  
  12. self.speed = 0.0
  13. self.wind_speed = 0.0
  14. self.wind_angle = 0.0
  15.  
  16. self.trail = [(boat_x, boat_y)]
  17.  
  18. self.no_go_limit = math.pi / 4
  19. self.tack_angle = math.radians(50)
  20. self.tack_side = 1
  21.  
  22. def set_wind(self, wind_speed, wind_x, wind_y):
  23. self.wind_speed = wind_speed
  24. self.wind_x = wind_x
  25. self.wind_y = wind_y
  26. self.wind_angle = math.atan2(wind_y, wind_x)
  27.  
  28. def angle_to_goal(self):
  29. return math.atan2(self.goal_y - self.boat_y, self.goal_x - self.boat_x)
  30.  
  31. def move_fwd(self):
  32. goal_angle = self.angle_to_goal()
  33. rel_goal_wind = (goal_angle - self.wind_angle + math.pi) % (2 * math.pi) - math.pi
  34.  
  35. # no-go zone
  36. if -self.no_go_limit < rel_goal_wind < self.no_go_limit:
  37. print("Alert! No-go-zone reached. Changing tack!")
  38. self.heading_angle = self.wind_angle + self.tack_side * self.tack_angle
  39. self.rudder_angle = -0.8 * self.tack_side
  40. else:
  41. self.heading_angle = goal_angle
  42. self.rudder_angle = 0.0
  43.  
  44. # polar efficiency (very simplified)
  45. rel_heading_wind = (self.heading_angle - self.wind_angle + math.pi) % (2 * math.pi) - math.pi
  46. polar_efficiency = max(0, 1 + math.sin(rel_heading_wind))
  47. self.speed = self.wind_speed * 0.1 * polar_efficiency
  48.  
  49. # update position
  50. self.boat_x += self.speed * math.cos(self.heading_angle)
  51. self.boat_y += self.speed * math.sin(self.heading_angle)
  52. self.trail.append((self.boat_x, self.boat_y))
  53.  
  54. # Switch tacks midway (simple logic)
  55. if (self.tack_side == 1 and self.boat_x > self.goal_x / 2) or \
  56. (self.tack_side == -1 and self.boat_x < -self.goal_x / 2):
  57. self.tack_side *= -1
  58.  
  59. def distance_to_goal(self):
  60. return math.sqrt((self.goal_x - self.boat_x) ** 2 + (self.goal_y - self.boat_y) ** 2)
  61.  
  62.  
  63. def sail():
  64. boat = Boat(boat_x=0, boat_y=0, heading_angle=0, goal_x=100, goal_y=100)
  65. boat.set_wind(30, 0, -1)
  66.  
  67. for step in range(500):
  68. boat.move_fwd()
  69. if boat.distance_to_goal() < 5:
  70. print("Goal reached successfully!")
  71. break
  72.  
  73.  
  74.  
Advertisement
Add Comment
Please, Sign In to add comment