def get_jib_winch_position(self, apparentWindAngleRad, X1, X2):
        """
        Calculates the winch position of the jib according to the apparent wind angle.

        Arguments
        ---------
        float : apparentWindAngleRad
            The wind angle in radians

        float : X1
            Parameter for jib saturation function

        float : X2
            Parameter for jib saturation function

        Returns
        -------
        int
            The winch position of the jib
        """

        jibAngle = JibController.get_jib_angle(apparentWindAngleRad, X1, X2)
        smallChange = not ControllerOutputRefiner.lowPowerAngle(
            inputSignal=jibAngle, currAngle=self.__currJibAngleRad)

        if (self.__controlModeID
                == ControlModes.LOW_POWER.value) and (smallChange):
            winchPosition = JibController.get_winch_position(
                self.__currJibAngleRad, self.__winchQuantParam)
        else:
            self.__currJibAngleRad = jibAngle
            winchPosition = JibController.get_winch_position(
                jibAngle, self.__winchQuantParam)
        return winchPosition
 def test_getSailAngle_X1_X2_mid(self):
     X2_TEST = 3 * math.pi / 4 + 0.2
     X1_TEST = math.pi / 4 + 0.2
     self.assertAlmostEqual(
         JibController.get_jib_angle((X2_TEST + X1_TEST) / 2, X1_TEST,
                                     X2_TEST),
         sailbot_constants.JIB_CONTROLLER_MAX_SAIL_ANGLE / 2)
     self.assertAlmostEqual(
         JibController.get_jib_angle((X2_TEST * 0.75 + X1_TEST * 0.25),
                                     X1_TEST, X2_TEST),
         sailbot_constants.JIB_CONTROLLER_MAX_SAIL_ANGLE / 4)
     self.assertAlmostEqual(
         JibController.get_jib_angle((X2_TEST * 0.25 + X1_TEST * 0.75),
                                     X1_TEST, X2_TEST),
         sailbot_constants.JIB_CONTROLLER_MAX_SAIL_ANGLE * 0.75)
 def test_getSailAngle_apparentWindAngleZero(self):
     X1 = 0
     X2 = math.pi
     self.assertEqual(
         JibController.get_jib_angle(0, X1, X2),
         sailbot_constants.JIB_CONTROLLER_MAX_SAIL_ANGLE,
     )
 def test_getSailAngle_apparentWindAnglePositiveNotBounded(self):
     X1 = 0
     X2 = math.pi
     self.assertAlmostEqual(
         JibController.get_jib_angle(2 + 10 * math.pi, X1, X2),
         sailbot_constants.JIB_CONTROLLER_MAX_SAIL_ANGLE / (-math.pi) * 2 +
         sailbot_constants.JIB_CONTROLLER_MAX_SAIL_ANGLE,
     )
 def test_getSailAngle_apparentWindAngle_boundedBetweenPiAnd2Pi(self):
     X1 = 0
     X2 = math.pi
     self.assertAlmostEqual(
         JibController.get_jib_angle(3 / 2 * math.pi, X1, X2),
         sailbot_constants.JIB_CONTROLLER_MAX_SAIL_ANGLE / (-math.pi) *
         (math.pi / 2) + sailbot_constants.JIB_CONTROLLER_MAX_SAIL_ANGLE,
     )
 def test_getSailAngle_apparentWindAngleBetweenNegativePiAnd0(self):
     X1 = 0
     X2 = math.pi
     self.assertAlmostEqual(
         JibController.get_jib_angle(-2, X1, X2),
         sailbot_constants.JIB_CONTROLLER_MAX_SAIL_ANGLE / (-math.pi) * 2 +
         sailbot_constants.JIB_CONTROLLER_MAX_SAIL_ANGLE,
     )
 def test_quant_winch_position_360(self):
     quant_param = 360
     self.assertEqual(
         JibController.get_winch_position(math.pi / 5, quant_param), 144)
     self.assertEqual(
         JibController.get_winch_position(math.pi / 8, quant_param), 90)
     self.assertEqual(
         JibController.get_winch_position(math.pi / 16, quant_param), 45)
     self.assertEqual(
         JibController.get_winch_position(math.pi / 17, quant_param), 42)
     self.assertEqual(
         JibController.get_winch_position(math.pi / 3, quant_param), 239)
     self.assertEqual(
         JibController.get_winch_position(math.pi / 2.2, quant_param), 327)
     self.assertEqual(
         JibController.get_winch_position(math.pi / 2.5, quant_param), 288)
 def test_quant_winch_position_4(self):
     quant_param = 4
     self.assertEqual(
         JibController.get_winch_position(math.pi / 5, quant_param), 180)
     self.assertEqual(
         JibController.get_winch_position(math.pi / 8, quant_param), 90)
     self.assertEqual(
         JibController.get_winch_position(math.pi / 16, quant_param), 90)
     self.assertEqual(
         JibController.get_winch_position(math.pi / 17, quant_param), 0)
     self.assertEqual(
         JibController.get_winch_position(math.pi / 3, quant_param), 270)
     self.assertEqual(
         JibController.get_winch_position(math.pi / 2.2, quant_param), 360)
     self.assertEqual(
         JibController.get_winch_position(math.pi / 2.5, quant_param), 270)
Beispiel #9
0
def publishRudderWinchAngle():
    if (headingSetPointRad is not None and headingMeasureRad is not None
            and apparentWindAngleRad is not None
            and groundspeedKnots is not None):

        global rudderAngleRad

        heading_error = controller.get_heading_error(
            current_heading=headingMeasureRad,
            desired_heading=headingSetPointRad,
            apparent_wind_angle=apparentWindAngleRad)

        controller.switchControlMode(heading_error=heading_error,
                                     boat_speed=groundspeedKnots)

        rudderAngleRad = (controller.get_feed_back_gain(heading_error) *
                          heading_error)

        global sailAngle
        sailAngle = (int(
            SailController.get_sail_angle(apparentWindAngleRad) *
            (360 / (math.pi / 2))))

        global jibAngle
        jibAngle = (int(
            JibController.get_jib_angle(apparentWindAngleRad) *
            (360 / (math.pi / 2))))

        rudder_winch_actuation_angle_pub.publish(
            ControllerOutputRefiner.saturate(
                rudderAngleRad, sailbot_constants.MAX_ABS_RUDDER_ANGLE_RAD,
                -sailbot_constants.MAX_ABS_RUDDER_ANGLE_RAD),
            ControllerOutputRefiner.saturate(
                sailAngle, sailbot_constants.MAX_WINCH_POSITION,
                sailbot_constants.MIN_WINCH_POSITION),
            ControllerOutputRefiner.saturate(
                jibAngle, sailbot_constants.MAX_WINCH_POSITION,
                sailbot_constants.MIN_WINCH_POSITION))
 def test_getSailAngle_X2_varying(self):
     X1 = 0
     self.assertAlmostEqual(
         JibController.get_jib_angle(3 * math.pi / 4 + 0.01, X1,
                                     3 * math.pi / 4), 0)
 def test_getSailAngle_X1_varying(self):
     X2 = math.pi
     self.assertAlmostEqual(
         JibController.get_jib_angle(math.pi / 4 - 0.01, math.pi / 4, X2),
         sailbot_constants.JIB_CONTROLLER_MAX_SAIL_ANGLE)
 def test_getSailAngle_apparentWindAngleNegativePi(self):
     X1 = 0
     X2 = math.pi
     self.assertEqual(JibController.get_jib_angle(-math.pi, X1, X2), 0)
Beispiel #13
0
 def test_getSailAngle_apparentWindAngleBetween0AndPi(self):
     self.assertAlmostEqual(
         JibController.get_jib_angle(2),
         sailbot_constants.JIB_CONTROLLER_MAX_SAIL_ANGLE / (-math.pi) * 2 +
         sailbot_constants.JIB_CONTROLLER_MAX_SAIL_ANGLE,
     )
Beispiel #14
0
 def test_getSailAngle_apparentWindAnglePi(self):
     self.assertEqual(JibController.get_jib_angle(math.pi), 0)