Пример #1
0
    def save_target_init_values(self, tank, x, y):
        if not self.enabled:
            return

        dist = tank.get_distance_to(x, y)
        vt = Vector(tank.speedX, tank.speedY)

        tank_v = Vector(tank.x, tank.y)
        pt_v = Vector(x, y)
        d = pt_v - tank_v

        tank_d_v = Vector(1, 0).rotate(tank.angle)

        if vt.is_zero():
            vd_angle = 0
        else:
            vd_angle = vt.angle(d)

        if d.is_zero():
            self.last_target_time_init_values = (0, 0, 0, 0, 0, 0)

        self.last_target_time_init_values = (tank_d_v.angle(d), dist, vd_angle,
                                             vt.length(), tank.angular_speed,
                                             tank.crew_health /
                                             tank.crew_max_health)
Пример #2
0
    def save_target_init_values(self, tank, x, y):
        if not self.enabled:
            return

        dist = tank.get_distance_to(x, y)
        vt = Vector(tank.speedX, tank.speedY)

        tank_v = Vector(tank.x, tank.y)
        pt_v = Vector(x, y)
        d = pt_v - tank_v

        tank_d_v = Vector(1, 0).rotate(tank.angle)

        if vt.is_zero():
            vd_angle = 0
        else:
            vd_angle = vt.angle(d)

        if d.is_zero():
            self.last_target_time_init_values = (0, 0, 0, 0, 0, 0)

        self.last_target_time_init_values = (
            tank_d_v.angle(d),
            dist,
            vd_angle,
            vt.length(),
            tank.angular_speed,
            tank.crew_health/tank.crew_max_health
        )
Пример #3
0
    def estimate_time_to_position(self, x, y, tank):
        dist = tank.get_distance_to(x, y)
        vt = Vector(tank.speedX, tank.speedY)

        tank_v = Vector(tank.x, tank.y)
        pt_v = Vector(x, y)
        d = pt_v - tank_v

        if d.is_zero():
            return 0

        tank_d_v = Vector(1, 0).rotate(tank.angle)

        if vt.is_zero() or d.is_zero():
            vd_angle = 0
        else:
            vd_angle = vt.angle(d)

        if tank_d_v.is_zero() or d.is_zero():
            d_angle = 0
        else:
            d_angle = tank_d_v.angle(d)

        # Short distances fix
        if dist < 100:
            if fabs(d_angle) < LOW_ANGLE:
                v0 = vt.projection(d)
                return solve_quadratic(FICTIVE_ACCELERATION/2, v0, -dist)
                #return dist/6
            elif PI - fabs(d_angle) < LOW_ANGLE:
                v0 = vt.projection(d)
                return solve_quadratic(FICTIVE_ACCELERATION/2 * 0.75, v0, -dist)
                #return dist/6 /0.75

        if d.is_zero():
            values = (0, 0, 0, 0, 0, 0, 0, 1)
        else:

            values = (
                d_angle,
                dist,
                vd_angle,
                vt.length(),
                tank.angular_speed,
                tank.crew_health/tank.crew_max_health,
                d_angle ** 2,
                1
                )

        return sum([x * y for (x, y) in zip(values, TIME_ESTIMATION_COEF)])
Пример #4
0
    def estimate_time_to_position(self, x, y, tank):
        dist = tank.get_distance_to(x, y)
        vt = Vector(tank.speedX, tank.speedY)

        tank_v = Vector(tank.x, tank.y)
        pt_v = Vector(x, y)
        d = pt_v - tank_v

        if d.is_zero():
            return 0

        tank_d_v = Vector(1, 0).rotate(tank.angle)

        if vt.is_zero() or d.is_zero():
            vd_angle = 0
        else:
            vd_angle = vt.angle(d)

        if tank_d_v.is_zero() or d.is_zero():
            d_angle = 0
        else:
            d_angle = tank_d_v.angle(d)

        # Short distances fix
        if dist < 100:
            if fabs(d_angle) < LOW_ANGLE:
                v0 = vt.projection(d)
                return solve_quadratic(FICTIVE_ACCELERATION / 2, v0, -dist)
                #return dist/6
            elif PI - fabs(d_angle) < LOW_ANGLE:
                v0 = vt.projection(d)
                return solve_quadratic(FICTIVE_ACCELERATION / 2 * 0.75, v0,
                                       -dist)
                #return dist/6 /0.75

        if d.is_zero():
            values = (0, 0, 0, 0, 0, 0, 0, 1)
        else:

            values = (d_angle, dist, vd_angle, vt.length(), tank.angular_speed,
                      tank.crew_health / tank.crew_max_health, d_angle**2, 1)

        return sum([x * y for (x, y) in zip(values, TIME_ESTIMATION_COEF)])
Пример #5
0
    def inverse_kinematics(self, goal, tol_limit=0.05, max_iterations=100):
        '''
		Preforms Inverse Kinematics on the arm using the known lengths and last positions.
		This uses the FABRIK method.
		See the more information section for information on the FABRIK method.


		Parameters
		----------
		goal : arraylike or Point
			desired location in the format of [x,y,z]
		tol_limit : scalar (optional)
			tolerance between the desired location and actual one after iteration
		max_iterations : scalar (optional)
			maximum itterations that the function is allowed to run


		Returns
		-------
		q1 : scalar
			rotation of the base about the z axis
		q2 : scalar
			rotation of first link relative to the base
		q3 : scalar
			rotation of the second link relative to the first link
		q4 : scalar
			rotation of the third link relative to the second link
		x_joints : array_like
			x points for all the joint locations
		y_joints : array_like
			y points for all the joint locations
		z_joints : array_like
			z points for all the joint locations


		More Information
		----------------
		Overall algorithim:
			solve for unit vectors going backwards from the desired point to the original point
			of the joints, then forwards from the origin, see youtube video
			https://www.youtube.com/watch?v=UNoX65PRehA&t=817s

		'''
        if isinstance(goal, list):
            if len(goal) != 3:
                raise IndexError(
                    "goal unclear. Need x,y,z coordinates in Point or list form."
                )
            goal = Point(goal[0], goal[1], goal[2])

        # Find base rotation
        # Initial angle of where end effector is
        initial_base_roation = np.arctan2(self.y_joints[-1], self.x_joints[-1])

        # Desired angle
        # arctan2(y,x)
        self.q1 = np.arctan2(goal.y, goal.x)

        # Base rotation
        base_rotation = self.q1 - initial_base_roation

        # Base rotation matrix about z
        z_rot = np.array([[np.cos(base_rotation), -np.sin(base_rotation), 0.0],
                          [np.sin(base_rotation),
                           np.cos(base_rotation), 0.0], [0.0, 0.0, 1.0]])

        # Rotate the location of each joint by the base rotation
        # This will force the FABRIK algorithim to only solve
        # in two dimensions, else each joint will move as if it has
        # a 3 DOF range of motion

        point4 = Point(
            np.dot(z_rot,
                   [self.x_joints[3], self.y_joints[3], self.z_joints[3]]))
        point3 = Point(
            np.dot(z_rot,
                   [self.x_joints[2], self.y_joints[2], self.z_joints[2]]))
        point2 = Point(
            np.dot(z_rot,
                   [self.x_joints[1], self.y_joints[1], self.z_joints[1]]))
        point1 = Point(
            np.dot(z_rot,
                   [self.x_joints[0], self.y_joints[0], self.z_joints[0]]))

        # store starting point of the first joint
        starting_point1 = point1

        iterations = 0

        # Make sure the desired x,y,z point is reachable
        if Vector.magnitude(goal) > self.total_arm_length:
            print ' desired point is likely out of reach'

        for _ in range(1, max_iterations + 1):

            # backwards
            point3 = Vector.project_along_vector(goal, point3,
                                                 self.third_link_length)
            point2 = Vector.project_along_vector(point3, point2,
                                                 self.second_link_length)
            point1 = Vector.project_along_vector(point2, point1,
                                                 self.first_link_length)

            # forwards
            point2 = Vector.project_along_vector(point1, point2,
                                                 self.first_link_length)
            point3 = Vector.project_along_vector(point2, point3,
                                                 self.second_link_length)
            point4 = Vector.project_along_vector(point3, goal,
                                                 self.third_link_length)

            # Solve for tolerance between iterated point and desired x,y,z,
            tol = point4 - goal

            # Make tolerance relative to x,y,z
            tol = Vector.magnitude(tol)

            iterations = iterations + 1

            # Check if tolerance is within the specefied limit
            if tol < tol_limit:
                break

        # Re-organize points into a big matrix for plotting elsewhere
        self.p_joints = np.transpose([
            starting_point1.as_array(),
            point2.as_array(),
            point3.as_array(),
            point4.as_array()
        ])

        self.x_joints = self.p_joints[0]
        self.y_joints = self.p_joints[1]
        self.z_joints = self.p_joints[2]

        # Return the joint angles by finding the angles with the dot produt
        vector21 = Vector(point2 - point1)
        vector32 = Vector(point3 - point2)
        vector43 = Vector(point4 - point3)

        # returns -pi to pi
        self.q2 = np.arctan2(
            vector21.end.z, Vector.magnitude([vector21.end.x, vector21.end.y]))

        # Negative sign because of dh notation, a rotation away from the previous link
        # and towards the x-y plane is a negative moment about the relative z axis.
        # the relative z axis of each link is out of the page if looking at the arm
        # in 2D
        # the x axis in dh convention is typically along the link direction.

        self.q3 = -1.0 * vector21.angle(vector32)
        self.q4 = -1.0 * vector32.angle(vector43)

        return [
            self.q1, self.q2, self.q3, self.q4, self.x_joints, self.y_joints,
            self.z_joints
        ]