def new_goal(self):
        goal = self.moveto_as.accept_new_goal()
        self.desired_position = tools.position_from_posetwist(goal.posetwist)
        self.desired_orientation = tools.orientation_from_posetwist(
            goal.posetwist)
        #self.linear_tolerance = goal.linear_tolerance
        #self.angular_tolerance = goal.angular_tolerance

        rospy.loginfo('Desired position:' + str(self.desired_position))
        rospy.loginfo('Current position:' + str(self.current_position))
        rospy.loginfo('Desired orientation:' + str(self.desired_orientation))
        rospy.loginfo('Current orientation:' + str(self.current_orientation))
        rospy.loginfo('linear_tolerance:' + str(self.linear_tolerance))
        rospy.loginfo('angular_tolerance:' + str(self.angular_tolerance))
        # This controller doesn't handle desired twist
        #self.desired_twist = goal.posetwist.twist
        if (xyz_array(goal.posetwist.twist.linear).any()
                or xyz_array(goal.posetwist.twist.angular).any()):
            rospy.logwarn(
                'None zero are not handled by the tank steer trajectory generator. Setting twist to 0'
            )

        if np.linalg.norm(self.current_position -
                          self.desired_position) > self.orientation_radius:
            self.line = line(self.current_position, self.desired_position)
            self.redraw_line = True
        else:
            self.line = line(
                self.current_position,
                tools.normal_vector_from_rotvec(self.desired_orientation) +
                self.current_position)
            self.redraw_line = False
示例#2
0
	def new_goal(self):
		goal = self.moveto_as.accept_new_goal()
		self.desired_position = tools.position_from_posetwist(goal.posetwist)
		self.desired_orientation = tools.orientation_from_posetwist(goal.posetwist)
		#self.linear_tolerance = goal.linear_tolerance
		#self.angular_tolerance = goal.angular_tolerance

		rospy.loginfo('Desired position:' + str(self.desired_position))
		rospy.loginfo('Current position:' + str(self.current_position))
		rospy.loginfo('Desired orientation:' + str(self.desired_orientation))
		rospy.loginfo('Current orientation:' + str(self.current_orientation))
		rospy.loginfo('linear_tolerance:' + str(self.linear_tolerance))
		rospy.loginfo('angular_tolerance:' + str(self.angular_tolerance))
		# This controller doesn't handle desired twist
		#self.desired_twist = goal.posetwist.twist
		if (xyz_array(goal.posetwist.twist.linear).any() or 
			xyz_array(goal.posetwist.twist.angular).any() ):
			rospy.logwarn('None zero are not handled by the tank steer trajectory generator. Setting twist to 0')
		
		if np.linalg.norm(self.current_position - self.desired_position) > self.orientation_radius:
			self.line = line(self.current_position, self.desired_position)
			self.redraw_line = True
		else:
			self.line = line(self.current_position, tools.normal_vector_from_rotvec(self.desired_orientation) + self.current_position)
			self.redraw_line = False
示例#3
0
def pressureIntersec(
        point1, refCurve1, point2
):  # refCurve1 is required just to get the direction and material
    pres1 = point1[1] + 1.E-20
    vel1 = point1[0] + 1.E-20
    pres2 = point2[1] + 1.E-20
    vel2 = point2[0] + 1.E-20

    interEnd1 = refCurve1.interEnd
    intersecInterface = setting.interface[interEnd1].position
    direction = refCurve1.direction

    if (direction == 1):
        mat1 = setting.interface[interEnd1].previousMat
        mat2 = setting.interface[interEnd1].nextMat
    elif (direction == 0):
        mat1 = setting.interface[interEnd1].nextMat
        mat2 = setting.interface[interEnd1].previousMat

    mat1Z = material[mat1].Z
    mat2Z = material[mat2].Z
    presSign = pres1 / abs(pres1)

    p1 = [vel1, pres1]
    p2 = [vel1 + 1.E9, abs(pres1) - mat1Z * 1.E9]
    p3 = [vel2, pres2]
    p4 = [vel2 + 1.E9, abs(pres2) + mat2Z * 1.E9]

    l1 = tools.line(p1, p2)
    l2 = tools.line(p3, p4)

    newPoint = tools.intersection(l1, l2)

    return newPoint
示例#4
0
def pressureInterface(motherId, motherCurve, calculated):
    """ When a single curve crosses at an intersection """
    # id of the interface where the mothercurve lands
    interEnd = motherCurve.interEnd
    intersecInterface = setting.interface[interEnd].position
    direction = motherCurve.direction
    daughterCurve0Id = curveHeritage[motherId][0][0]
    daughterCurve1Id = curveHeritage[motherId][1][0]
    daughter0 = curve[daughterCurve0Id]
    daughter1 = curve[daughterCurve1Id]

    if (direction == 1):
        motherMat = setting.interface[interEnd].previousMat
        # daughterMat = material next to the mother where one of the shockwave will go
        daughterMat = setting.interface[interEnd].nextMat
    elif (direction == 0):
        motherMat = setting.interface[interEnd].nextMat
        daughterMat = setting.interface[interEnd].previousMat

    motherMatZ = material[motherMat].Z
    daughterMatZ = material[daughterMat].Z
    motherVel = motherCurve.velocity
    motherPres = motherCurve.pressure
    presSign = motherPres / abs(motherPres)

    # pressure of the outgoing curve that has the same direction as the mothercurve
    p1 = [motherVel, motherPres]
    p2 = [motherVel + 1.E9, presSign * (abs(motherPres) - motherMatZ * 1.E9)]
    l1 = tools.line(p1, p2)
    # next material hugoniot
    p3 = [0., 0.]
    p4 = [1.E9, presSign * daughterMatZ * 1E9]
    l2 = tools.line(p3, p4)
    # intersection of both hugoniot
    newPoint = tools.intersection(l1, l2)
    daughter1.velocity = newPoint[0]
    daughter1.pressure = newPoint[1]
    calculated[daughterCurve1Id] = newPoint
    presSign = daughter1.pressure / abs(daughter1.pressure)
    # pressure of the outgoing curve that has the opposite direction than the mothercurve
    p1 = [daughter1.velocity, daughter1.pressure]
    p2 = [
        daughter1.velocity + 1.E9,
        daughter1.pressure + presSign * motherMatZ * 1.E9
    ]
    l1 = tools.line(p1, p2)
    p3 = [0., 0.]
    p4 = [1.E9, presSign * (-motherMatZ) * 1.E9]
    l2 = tools.line(p3, p4)
    newPoint = tools.intersection(l1, l2)
    calculated[daughterCurve0Id] = newPoint
    daughter0.velocity = newPoint[0]
    daughter0.pressure = newPoint[1]

    return
示例#5
0
	def __init__(self, name):
		# Desired pose
		self.desired_position = self.current_position = np.zeros(3)
		self.desired_orientation = self.current_orientation = np.zeros(3)
		#self.desired_twist = self.current_twist = Twist()

		# Goal tolerances before seting succeded
		self.linear_tolerance = rospy.get_param('linear_tolerance', 0.5)
		self.angular_tolerance = rospy.get_param('angular_tolerance', np.pi / 10)
		self.orientation_radius = rospy.get_param('orientation_radius', 0.75)
		self.slow_down_radius = rospy.get_param('slow_down_radius', 5)

		# Speed parameters
		self.max_tracking_distance = rospy.get_param('max_tracking_distance', 5)
		self.min_tracking_distance = rospy.get_param('min_tracking_distance', 1)
		self.tracking_to_speed_conv = rospy.get_param('tracking_to_speed_conv', 1)
		self.tracking_slope = (self.max_tracking_distance - self.min_tracking_distance) / (self.slow_down_radius - self.orientation_radius)
		self.tracking_intercept = self.tracking_slope * self.orientation_radius + self.min_tracking_distance

		# Publishers
		self.traj_pub = rospy.Publisher('/trajectory', PoseTwistStamped, queue_size = 10)

		# Set desired twist to 0
		#self.desired_twist.linear.x = self.desired_twist.linear.y = self.desired_twist.linear.z = 0
		#self.desired_twist.angular.x = self.desired_twist.angular.y = self.desired_twist.angular.z = 0

		# Initilize a line
		self.line = line(np.zeros(3), np.ones(3))

		# Wait for current position and set as desired position
		rospy.loginfo('Waiting for /odom')
		self.odom_sub = rospy.Subscriber('/odom', Odometry, self.odom_cb, queue_size = 10)
		while not self.current_position.any():	# Will be 0 until an odom publishes (if its still 0 it will drift very very soon)
			pass

		# Initlize Trajectory generator with current position as goal
		# 	Set the line to be along our current orientation
		self.desired_position = self.current_position
		self.desired_orientation = self.current_orientation
		# 	Make a line along the orientation
		self.line = line(self.current_position, tools.normal_vector_from_rotvec(self.current_orientation) + self.current_position)
		self.redraw_line = False
		rospy.loginfo('Got current pose from /odom')

		# Kill handling
		self.killed = False
		self.kill_listener = KillListener(self.set_kill, self.clear_kill)
		self.kill_broadcaster = KillBroadcaster(id=name, description='Tank steer trajectory_generator shutdown')
		try:
			self.kill_broadcaster.clear()			# In case previously killed
		except rospy.service.ServiceException, e:
			rospy.logwarn(str(e))
示例#6
0
    def feedback(self, pt):
        # Update current pt
        self.current_position = tools.position_from_posetwist(pt)
        # Zero the Z
        self.current_position[2] = 0
        self.current_orientation = tools.orientation_from_posetwist(pt)

        # Get distance to the goal
        if np.array_equal(self.current_position, self.desired_position):
            self.line = line(self.desired_position, tools.normal_vector_from_rotvec(self.desired_orientation) + self.desired_position)
        else:
            self.line = line(self.current_position, self.desired_position)

        self.distance_to_goal = np.linalg.norm(self.line.s)
示例#7
0
    def new_goal(self, goal):
        self.desired_position = tools.position_from_posetwist(goal)
        self.desired_orientation = tools.orientation_from_posetwist(goal)

        # Twist not supported
        if (xyz_array(goal.twist.linear).any() or 
            xyz_array(goal.twist.angular).any() ):
            rospy.logwarn('None zero twist are not handled by the azi point and shoot trajectory generator. Setting twist to 0')

        if np.linalg.norm(self.current_position - self.desired_position) > self.orientation_radius:
            #print 'Far out dude'
            self.line = line(self.current_position, self.desired_position)
        else:
            #print 'Pretty close'
            self.line = line(self.desired_position, tools.normal_vector_from_rotvec(self.desired_orientation) + self.desired_position)
    def update(self, event):

        # Publish trajectory
        traj = self.get_carrot()
        #rospy.loginfo('Trajectory: ' + str(traj))
        if not self.killed:
            self.traj_pub.publish(traj)

        if self.redraw_line and self.distance_to_goal < self.orientation_radius:
            self.redraw_line = False
            rospy.loginfo('Redrawing trajectory line')
            self.line = line(
                self.current_position,
                tools.normal_vector_from_rotvec(self.desired_orientation) +
                self.current_position)

        rospy.loginfo('Angle to goal: ' +
                      str(self.angle_to_goal_orientation[2] * 180 / np.pi) +
                      '\t\t\tDistance to goal: ' + str(self.distance_to_goal))

        # Check if goal is reached
        if self.moveto_as.is_active():
            if self.distance_to_goal < self.linear_tolerance:
                if self.angle_to_goal_orientation[2] < self.angular_tolerance:
                    rospy.loginfo('succeded')
                    self.moveto_as.set_succeeded(None)
示例#9
0
    def update(self):
        # Check if in the orientation radius for the first time
        if self.redraw_line and self.distance_to_goal < self.orientation_radius:
            self.redraw_line = False
            rospy.loginfo('Redrawing trajectory line')
            self.line = line(self.desired_position, tools.normal_vector_from_rotvec(self.desired_orientation) + self.desired_position)

        # Output a posetwist (carrot)
        # Project current position onto trajectory line
        Bproj = self.line.proj_pt(self.current_position)
        parallel_distance = np.linalg.norm(self.desired_position - Bproj)

        # Move carrot along line
        tracking_step = self.get_tracking_distance()
        c_pos = Bproj + self.overshoot * self.line.hat * tracking_step

        # If bproj is in threashold just set the carrot to the final position
        if parallel_distance < self.orientation_radius:
            c_pos = self.desired_position      

        # Fill up PoseTwist
        carrot = PoseTwist(
                pose = Pose(
                    position = tools.vector3_from_xyz_array(c_pos),
                    orientation = tools.quaternion_from_rotvec([0, 0, self.line.angle])),

                twist = Twist(
                    linear = Vector3(tracking_step * self.tracking_to_speed_conv * self.overshoot, 0, 0),        # Wrench Generator handles the sine of the velocity
                    angular = Vector3())
                )
        return carrot
示例#10
0
    def update(self):
        # Check if in the orientation radius for the first time
        if self.redraw_line and self.distance_to_goal < self.orientation_radius:
            self.redraw_line = False
            rospy.loginfo('Redrawing trajectory line')
            self.line = line(
                self.desired_position,
                tools.normal_vector_from_rotvec(self.desired_orientation) +
                self.desired_position)

        # Output a posetwist (carrot)
        # Project current position onto trajectory line
        Bproj = self.line.proj_pt(self.current_position)
        parallel_distance = np.linalg.norm(self.desired_position - Bproj)

        # Move carrot along line
        tracking_step = self.get_tracking_distance()
        c_pos = Bproj + self.overshoot * self.line.hat * tracking_step

        # If bproj is in threashold just set the carrot to the final position
        if parallel_distance < self.orientation_radius:
            c_pos = self.desired_position

        # Fill up PoseTwist
        carrot = PoseTwist(
            pose=Pose(position=tools.vector3_from_xyz_array(c_pos),
                      orientation=tools.quaternion_from_rotvec(
                          [0, 0, self.line.angle])),
            twist=Twist(
                linear=Vector3(
                    tracking_step * self.tracking_to_speed_conv *
                    self.overshoot, 0,
                    0),  # Wrench Generator handles the sine of the velocity
                angular=Vector3()))
        return carrot
示例#11
0
    def __init__(self):
        # Desired pose
        self.desired_position = self.current_position = np.zeros(3)
        self.desired_orientation = self.current_orientation = np.zeros(3)

        # Region deffinitions
        self.orientation_radius = rospy.get_param('orientation_radius', 1)
        self.slow_down_radius = rospy.get_param('slow_down_radius', 3.0)

        # Speed parameters
        self.max_tracking_distance = rospy.get_param('max_tracking_distance',
                                                     2.0)
        self.min_tracking_distance = rospy.get_param(
            'min_tracking_distance', 0.5)  # Half orientation radius
        self.tracking_to_speed_conv = rospy.get_param('tracking_to_speed_conv',
                                                      1.0)
        self.tracking_slope = (
            self.max_tracking_distance - self.min_tracking_distance) / (
                self.slow_down_radius - self.orientation_radius)
        self.tracking_intercept = self.min_tracking_distance - self.tracking_slope * self.orientation_radius

        # Goal paramiters
        self.distance_to_goal = 0.0

        # Initilize a line
        self.redraw_line = True
        self.line = line(np.zeros(3), np.ones(3))
示例#12
0
    def feedback(self, pt):
        # Update current pt
        self.current_position = tools.position_from_posetwist(pt)
        # Zero the Z
        self.current_position[2] = 0
        self.current_orientation = tools.orientation_from_posetwist(pt)

        # Get distance to the goal
        if np.array_equal(self.current_position, self.desired_position):
            self.line = line(
                self.desired_position,
                tools.normal_vector_from_rotvec(self.desired_orientation) +
                self.desired_position)
        else:
            self.line = line(self.current_position, self.desired_position)

        self.distance_to_goal = np.linalg.norm(self.line.s)
示例#13
0
def pressureCross(point1, refCurve1, point2,
                  refCurve2):  # refCurve1 is required just to get the material
    pres1 = point1[1] + 1.E-13
    vel1 = point1[0] + 1.E-13
    pres2 = point2[1] + 1.E-13
    vel2 = point2[0] + 1.E-13

    interEnd1 = refCurve1.interEnd
    interEnd2 = refCurve2.interEnd

    mat1 = setting.interface[interEnd1].previousMat
    mat2 = setting.interface[interEnd2].nextMat

    mat1Z = material[mat1].Z
    mat2Z = material[mat2].Z
    presSign = pres1 / abs(pres1)
    velSign = vel1 / abs(vel1)

    p1 = [vel1, pres1]
    p2 = [vel1 + 1.E9, abs(pres1) - mat1Z * 1.E9]
    p3 = [vel2, pres2]
    p4 = [vel2 + 1.E9, abs(pres2) + mat2Z * 1.E9]

    if mat1Z == mat2Z:
        if pres1 / pres2 > 0:
            if vel1 < vel2:
                p2 = [vel1 + 1.E9, abs(pres1) + presSign * mat1Z * 1.E9]
                p4 = [vel2 + 1.E9, abs(pres2) - presSign * mat2Z * 1.E9]
            else:
                p2 = [vel1 + 1.E9, abs(pres1) - presSign * mat1Z * 1.E9]
                p4 = [vel2 + 1.E9, abs(pres2) + presSign * mat2Z * 1.E9]
        elif vel1 / vel2 > 0:
            if pres1 < pres2:
                p2 = [vel1 + 1.E9, abs(pres1) + presSign * mat1Z * 1.E9]
                p4 = [vel2 + 1.E9, abs(pres2) - presSign * mat2Z * 1.E9]
            else:
                p2 = [vel1 + 1.E9, abs(pres1) - presSign * mat1Z * 1.E9]
                p4 = [vel2 + 1.E9, abs(pres2) + presSign * mat2Z * 1.E9]
    l1 = tools.line(p1, p2)
    l2 = tools.line(p3, p4)

    newPoint = tools.intersection(l1, l2)

    return newPoint
示例#14
0
def look_for(search, database, text1, text2, text3="(Press 1 to quit this option)"):
    name = input(f"Please enter {search} you are looking for:\n").capitalize()
    temp = 0
    while name not in database:
        for data in database:
            if name.lower() == data.lower():
                return data
            if re.search(name.lower(), data.lower()):
                temp += 1
                if temp == 1:
                    print_with_nl("Here are some suggestions:")
                print(data)
        if name == '1':
            return
        line()
        name = input(
            f"There is {text1} '{capwords(name)}' in my database."
            f"\nPlease enter {text2}\n{text3}\n")
    line()
    return name
示例#15
0
    def new_goal(self, goal):
        self.desired_position = tools.position_from_posetwist(goal)
        self.desired_orientation = tools.orientation_from_posetwist(goal)

        # Twist not supported
        if (xyz_array(goal.twist.linear).any()
                or xyz_array(goal.twist.angular).any()):
            rospy.logwarn(
                'None zero twist are not handled by the azi point and shoot trajectory generator. Setting twist to 0'
            )

        if np.linalg.norm(self.current_position -
                          self.desired_position) > self.orientation_radius:
            #print 'Far out dude'
            self.line = line(self.current_position, self.desired_position)
        else:
            #print 'Pretty close'
            self.line = line(
                self.desired_position,
                tools.normal_vector_from_rotvec(self.desired_orientation) +
                self.desired_position)
示例#16
0
    def start(self, current_pt):
        # Set current position and twist
        self.current_position = tools.position_from_posetwist(current_pt)
        # Zero the Z
        self.current_position[2] = 0
        self.current_orientation = tools.orientation_from_posetwist(current_pt)

        # Initlize Trajectory generator with current position as goal
        #   Set the line to be along our current orientation
        self.desired_position = self.current_position
        self.desired_orientation = self.current_orientation
        #   Make a line along the orientation
        self.line = line(self.current_position, tools.normal_vector_from_rotvec(self.current_orientation) + self.current_position)
示例#17
0
    def start(self, current_pt):
        # Set current position and twist
        self.current_position = tools.position_from_posetwist(current_pt)
        # Zero the Z
        self.current_position[2] = 0
        self.current_orientation = tools.orientation_from_posetwist(current_pt)

        # Initlize Trajectory generator with current position as goal
        #   Set the line to be along our current orientation
        self.desired_position = self.current_position
        self.desired_orientation = self.current_orientation
        #   Make a line along the orientation
        self.line = line(self.current_position, tools.normal_vector_from_rotvec(self.current_orientation) + self.current_position)
        self.redraw_line = False
示例#18
0
def pressureMultRef(point, inc):
    refCurve = curve[inc[0]]
    interEnd = refCurve.interEnd

    if (refCurve.direction == 1):
        mat = setting.interface[interEnd].previousMat
    else:
        mat = setting.interface[interEnd].nextMat
    matZ = material[mat].Z
    presSign = point[1] / abs(point[1] + 1.e-13)

    if (point[0] < 0):
        p2 = [point[0] + 1., presSign * (abs(point[1]) + matZ)]
    else:
        p2 = [point[0] + 1., presSign * (abs(point[1]) - matZ)]
    p1 = [point[0], point[1]]
    p3 = [0, 0]
    p4 = [1, 0]
    l1 = tools.line(p1, p2)
    l2 = tools.line(p3, p4)

    newPoint = tools.intersection(l1, l2)

    return newPoint
示例#19
0
    def __init__(self):
        # Desired pose
        self.desired_position = self.current_position = np.zeros(3)
        self.desired_orientation = self.current_orientation = np.zeros(3)

        # Region deffinitions
        self.orientation_radius = rospy.get_param('orientation_radius', 2)
        self.slow_down_radius = rospy.get_param('slow_down_radius', 3.0)

        # Speed parameters
        self.max_tracking_distance = rospy.get_param('max_tracking_distance', 2.0)
        self.min_tracking_distance = rospy.get_param('min_tracking_distance', 0.5)      # Half orientation radius
        self.tracking_to_speed_conv = rospy.get_param('tracking_to_speed_conv', 1.0)
        self.tracking_slope = (self.max_tracking_distance - self.min_tracking_distance) / (self.slow_down_radius - self.orientation_radius)
        self.tracking_intercept = self.min_tracking_distance - self.tracking_slope * self.orientation_radius

        # Goal paramiters
        self.distance_to_goal = 0.0

        # Initilize a line
        self.line = line(np.zeros(3), np.ones(3))
示例#20
0
	def update(self, event):
		
		# Publish trajectory
		traj = self.get_carrot()
		#rospy.loginfo('Trajectory: ' + str(traj))
		if not self.killed:
			self.traj_pub.publish(traj)

		if self.redraw_line and self.distance_to_goal < self.orientation_radius:
			self.redraw_line = False
			rospy.loginfo('Redrawing trajectory line')
			self.line = line(self.current_position, tools.normal_vector_from_rotvec(self.desired_orientation) + self.current_position)

		rospy.loginfo('Angle to goal: ' + str(self.angle_to_goal_orientation[2] * 180 / np.pi) + '\t\t\tDistance to goal: ' + str(self.distance_to_goal))

		# Check if goal is reached
		if self.moveto_as.is_active():
			if self.distance_to_goal < self.linear_tolerance:
				if self.angle_to_goal_orientation[2] < self.angular_tolerance:
					rospy.loginfo('succeded')
					self.moveto_as.set_succeeded(None)
示例#21
0
    def traj_cb(self, traj):
        # Timing
        now = rospy.get_rostime()
        dt = (now - self.last_time).to_sec()
        self.last_time = now

        # Get vectors related to the orientation of the trajectory
        o = tools.normal_vector_from_posetwist(traj.posetwist)
        #rospy.loginfo('o : ' + str(o))
        o_hat = o / np.linalg.norm(o)
        #rospy.loginfo('o hat: ' + str(o_hat))
        o_norm = np.cross([0, 0, -1], o_hat)
        #rospy.loginfo('o norm: ' + str(o_norm))

        # Overshoot = 1 if the boat is behind a line drawn perpendicular to the trajectory orientation
        #		and through the trajectories position, it is -1 if it is on the other side of the before mentioned line
        traj_position = tools.position_from_posetwist(traj.posetwist)
        boat_proj = line(traj_position,
                         traj_position + o_hat).proj_pt(self.current_position)
        #rospy.loginfo('Boat_proj: ' + str(boat_proj))
        #rospy.loginfo('traj: ' + str(traj_position))
        #rospy.loginfo('traj - Boat_proj: ' + str(traj_position - boat_proj))
        boat_to_traj = traj_position - self.current_position
        boat_dist_to_traj = np.linalg.norm(boat_to_traj)
        boat_to_traj_hat = boat_to_traj / boat_dist_to_traj
        boat_to_traj_norm = np.cross([0, 0, -1], boat_to_traj_hat)
        overshoot = np.dot(boat_to_traj_hat, o_hat)
        overshoot = overshoot / abs(overshoot)
        rospy.loginfo('overshoot: ' + str(overshoot))
        if math.isnan(overshoot):
            return

        # Method 2:
        #
        ##		P error = - angle(between boat and trajectory)
        #
        #enu_angle_to_traj = np.arccos(boat_to_traj_hat, np.array([1, 0, 0])))
        #enu_angle_to_traj = math.copysign(enu_angle_to_traj, np.dot(boat_to_traj_norm, self.current_position))
        #boat_angle_to_traj = (self.current_orientation[2] - enu_angle_to_traj) % (np.pi)

        boat_orientation_vec = tools.normal_vector_from_rotvec(
            self.current_orientation)

        #angle_error = 0
        #torque_dir = 1
        if boat_dist_to_traj > self.orientation_radius:
            rospy.loginfo('Location: Outside orientation radius')
            # Is the angle to trajectory positive or negative ( dot product of two unit vectors is negative when the
            # angle between them is greater than 90, by doting the orientation of the boat with a vector that is 90 degrees
            # to the trajectory and pointed to the right  we get positive numbers if we are pointed to the right and negative
            # if we are on the left side)
            torque_dir = math.copysign(
                1, np.dot(boat_to_traj_norm, boat_orientation_vec))
            # angle between path to traj and boat orientation
            angle_error = np.arccos(
                np.dot(boat_orientation_vec, boat_to_traj_hat))
        else:
            rospy.loginfo('Location: Inside orientation radius')
            # Same as above but now we are orienting to the desired final orientation instead of towards the trajectory
            torque_dir = math.copysign(1, np.dot(o_norm, boat_orientation_vec))
            # Angle between traj_orientation and boat orientation
            angle_error = np.arccos(np.dot(boat_orientation_vec, o_hat))

        #rospy.loginfo('enu_angle_to_traj:\t' + str(enu_angle_to_traj * 180 / np.pi))
        #rospy.loginfo('Boat orientation:\t' + str(self.current_orientation[2] * 180 / np.pi))
        #rospy.loginfo('Boat angle to traj\t' + str((boat_angle_to_traj) * 180 / np.pi ))

        torque = angle_error * torque_dir * self.p
        force = traj.posetwist.twist.linear.x
        if boat_dist_to_traj < self.orientation_radius and overshoot == -1:
            rospy.loginfo('Status: Overshoot in orientation radius')
            force = force * -1
        elif abs(angle_error) > np.pi / 2:
            rospy.loginfo('Status: angle error > 90')
            force = 0
        else:
            rospy.loginfo('Status: Normal')

        rospy.loginfo('Angle error: ' +
                      str(angle_error * torque_dir * 180 / np.pi))

        rospy.loginfo('torque: ' + str(torque))
        rospy.loginfo('Force: ' + str(force))
        """ Method 1:
		#
		##		P error = - perpendicular_velocity * p_gain * overshoot
		#
		# Velocity error = velocity perpendicular to trajectory orientation
		velocity_error = self.current_velocity - (np.dot(self.current_velocity, o_hat) * o_hat)
		v_dir = np.dot(velocity_error, o_norm)
		velocity_error = math.copysign(np.linalg.norm(velocity_error), v_dir)
		rospy.loginfo('V_perp = ' + str(velocity_error))
		velocity_error = -1 * velocity_error * self.p * overshoot
		rospy.loginfo('P error = ' + str(velocity_error))

		#
		##		I error = - position * i_gain * overshoot * ???
		#
		# Positional error
		#				boat_position		parralel portion of boat position
		pos_error = self.current_position - boat_proj
		p_dir = np.dot(pos_error, o_norm)
		pos_error = math.copysign(np.linalg.norm(pos_error), p_dir)
		rospy.loginfo('Perp_position = ' + str(pos_error))
		pos_error = -1 * pos_error * self.i * overshoot
		rospy.loginfo('I error = ' + str(pos_error))

		#
		##		D error
		#
		# Acceleration error
		acceleration_error = self.d * (velocity_error - self.last_perp_velocity) / dt
		self.last_perp_velocity = velocity_error

		torque = velocity_error + pos_error + acceleration_error


		# Reverse force if overshoot
		force = traj.posetwist.twist.linear.x * overshoot
		rospy.loginfo('torque: ' + str(torque))
		"""

        # Output a wrench!
        if not self.killed:
            self.wrench_pub.publish(
                WrenchStamped(header=Header(frame_id='/base_link', stamp=now),
                              wrench=Wrench(force=Vector3(force, 0, 0),
                                            torque=Vector3(0, 0, torque))))
        else:
            # Publish zero wrench
            self.wrench_pub.publish(WrenchStamped())
示例#22
0
def pressureMultInt(
    point, inc
):  # value of pressure and velocity for incomming curves, list inc curves, list outgoing curves
    """ When multiple curve crosses at an intersection """
    pres1 = point[1] + 1E-13
    vel1 = point[0]
    direction = curve[inc[0]].direction

    refCurve = curve[inc[0]]
    interEnd = refCurve.interEnd

    if (direction == 1):
        mat1 = setting.interface[interEnd].previousMat
        mat2 = setting.interface[interEnd].nextMat
    elif (direction == 0):
        mat1 = setting.interface[interEnd].nextMat
        mat2 = setting.interface[interEnd].previousMat

    mat1Z = material[mat1].Z
    mat2Z = material[mat2].Z
    presSign = pres1 / abs(pres1)

    p1 = [vel1, pres1]
    if vel1 >= 0:
        p2 = [vel1 + 1.E9, presSign * (abs(pres1) - mat1Z * 1.E9)]
    else:
        p2 = [vel1 + 1.E9, presSign * (abs(pres1) + mat1Z * 1.E9)]
    l1 = tools.line(p1, p2)
    p3 = [0., 0.]
    if vel1 >= 0:
        p4 = [1.E9, presSign * mat2Z * 1.E9]
    else:
        p4 = [-1.E9, presSign * mat2Z * 1.E9]
    l2 = tools.line(p3, p4)
    temp1 = tools.intersection(l1, l2)

    p1 = [temp1[0], temp1[1]]
    if vel1 >= 0:
        p2 = [temp1[0] + 1.E9, temp1[1] + presSign * mat1Z * 1.E9]
    else:
        p2 = [temp1[0] + 1.E9, temp1[1] - presSign * mat1Z * 1.E9]
    l1 = tools.line(p1, p2)
    # next material hugoniot
    p3 = [0., 0.]
    if vel1 >= 0:
        p4 = [1.E9, presSign * (-mat1Z) * 1.E9]
    else:
        p4 = [1.E9, presSign * (mat1Z) * 1.E9]
    l2 = tools.line(p3, p4)
    temp2 = tools.intersection(l1, l2)

    if (direction == 0):
        if refCurve.cType == 0:
            if mat1Z < mat2Z:
                if abs(temp2[1]) < abs(temp1[1]):
                    topL = temp1
                    topR = temp2
                else:
                    topL = temp2
                    topR = temp1
            else:
                if temp2[1] / pres1 < 0:
                    topL = temp1
                    topR = temp2
                else:
                    topL = temp2
                    topR = temp1
        else:
            if mat1Z < mat2Z:
                if abs(temp2[1]) < abs(temp1[1]):
                    topL = temp1
                    topR = temp2
                else:
                    topL = temp2
                    topR = temp1
            else:
                if temp2[1] / pres1 < 0:
                    topL = temp1
                    topR = temp2
                else:
                    topL = temp2
                    topR = temp1
    elif (direction == 1):
        if refCurve.cType == 0:
            if mat1Z < mat2Z:
                if abs(temp2[1]) < abs(temp1[1]):
                    topR = temp1
                    topL = temp2
                else:
                    topR = temp2
                    topL = temp1
            else:
                if temp2[1] / pres1 < 0:
                    topR = temp1
                    topL = temp2
                else:
                    topR = temp2
                    topL = temp1
        else:
            if mat1Z < mat2Z:
                if abs(temp2[1]) < abs(temp1[1]):
                    topR = temp1
                    topL = temp2
                else:
                    topR = temp2
                    topL = temp1
            else:
                if temp2[1] / pres1 < 0:
                    topR = temp1
                    topL = temp2
                else:
                    topR = temp2
                    topL = temp1

    return topL, topR
示例#23
0
    def __init__(self, name):
        # Desired pose
        self.desired_position = self.current_position = np.zeros(3)
        self.desired_orientation = self.current_orientation = np.zeros(3)
        #self.desired_twist = self.current_twist = Twist()

        # Goal tolerances before seting succeded
        self.linear_tolerance = rospy.get_param('linear_tolerance', 0.5)
        self.angular_tolerance = rospy.get_param('angular_tolerance',
                                                 np.pi / 10)
        self.orientation_radius = rospy.get_param('orientation_radius', 0.75)
        self.slow_down_radius = rospy.get_param('slow_down_radius', 5)

        # Speed parameters
        self.max_tracking_distance = rospy.get_param('max_tracking_distance',
                                                     5)
        self.min_tracking_distance = rospy.get_param('min_tracking_distance',
                                                     1)
        self.tracking_to_speed_conv = rospy.get_param('tracking_to_speed_conv',
                                                      1)
        self.tracking_slope = (
            self.max_tracking_distance - self.min_tracking_distance) / (
                self.slow_down_radius - self.orientation_radius)
        self.tracking_intercept = self.tracking_slope * self.orientation_radius + self.min_tracking_distance

        # Publishers
        self.traj_pub = rospy.Publisher('/trajectory',
                                        PoseTwistStamped,
                                        queue_size=10)

        # Set desired twist to 0
        #self.desired_twist.linear.x = self.desired_twist.linear.y = self.desired_twist.linear.z = 0
        #self.desired_twist.angular.x = self.desired_twist.angular.y = self.desired_twist.angular.z = 0

        # Initilize a line
        self.line = line(np.zeros(3), np.ones(3))

        # Wait for current position and set as desired position
        rospy.loginfo('Waiting for /odom')
        self.odom_sub = rospy.Subscriber('/odom',
                                         Odometry,
                                         self.odom_cb,
                                         queue_size=10)
        while not self.current_position.any(
        ):  # Will be 0 until an odom publishes (if its still 0 it will drift very very soon)
            pass

        # Initlize Trajectory generator with current position as goal
        # 	Set the line to be along our current orientation
        self.desired_position = self.current_position
        self.desired_orientation = self.current_orientation
        # 	Make a line along the orientation
        self.line = line(
            self.current_position,
            tools.normal_vector_from_rotvec(self.current_orientation) +
            self.current_position)
        self.redraw_line = False
        rospy.loginfo('Got current pose from /odom')

        # Kill handling
        self.killed = False
        self.kill_listener = KillListener(self.set_kill, self.clear_kill)
        self.kill_broadcaster = KillBroadcaster(
            id=name, description='Tank steer trajectory_generator shutdown')
        try:
            self.kill_broadcaster.clear()  # In case previously killed
        except rospy.service.ServiceException, e:
            rospy.logwarn(str(e))
示例#24
0
	def traj_cb(self, traj):
		# Timing
		now = rospy.get_rostime()
		dt = (now - self.last_time).to_sec()
		self.last_time = now

		# Get vectors related to the orientation of the trajectory
		o = tools.normal_vector_from_posetwist(traj.posetwist)
		#rospy.loginfo('o : ' + str(o))
		o_hat = o / np.linalg.norm(o)
		#rospy.loginfo('o hat: ' + str(o_hat))
		o_norm = np.cross([0, 0, -1], o_hat)
		#rospy.loginfo('o norm: ' + str(o_norm))

		# Overshoot = 1 if the boat is behind a line drawn perpendicular to the trajectory orientation
		#		and through the trajectories position, it is -1 if it is on the other side of the before mentioned line
		traj_position = tools.position_from_posetwist(traj.posetwist)
		boat_proj = line(traj_position, traj_position + o_hat).proj_pt(self.current_position)
		#rospy.loginfo('Boat_proj: ' + str(boat_proj))
		#rospy.loginfo('traj: ' + str(traj_position))
		#rospy.loginfo('traj - Boat_proj: ' + str(traj_position - boat_proj))
		boat_to_traj = traj_position - self.current_position
		boat_dist_to_traj = np.linalg.norm(boat_to_traj)
		boat_to_traj_hat = boat_to_traj / boat_dist_to_traj
		boat_to_traj_norm = np.cross([0,0,-1], boat_to_traj_hat)
		overshoot = np.dot(boat_to_traj_hat, o_hat)
		overshoot = overshoot / abs(overshoot)
		rospy.loginfo('overshoot: ' + str(overshoot))
		if math.isnan(overshoot):
			return

		# Method 2:
		#
		##		P error = - angle(between boat and trajectory)
		#
		#enu_angle_to_traj = np.arccos(boat_to_traj_hat, np.array([1, 0, 0])))
		#enu_angle_to_traj = math.copysign(enu_angle_to_traj, np.dot(boat_to_traj_norm, self.current_position))
		#boat_angle_to_traj = (self.current_orientation[2] - enu_angle_to_traj) % (np.pi)


		boat_orientation_vec = tools.normal_vector_from_rotvec(self.current_orientation)

		#angle_error = 0
		#torque_dir = 1
		if boat_dist_to_traj > self.orientation_radius:
			rospy.loginfo('Location: Outside orientation radius')
			# Is the angle to trajectory positive or negative ( dot product of two unit vectors is negative when the 
				# angle between them is greater than 90, by doting the orientation of the boat with a vector that is 90 degrees
				# to the trajectory and pointed to the right  we get positive numbers if we are pointed to the right and negative 
				# if we are on the left side)
			torque_dir = math.copysign(1, np.dot(boat_to_traj_norm, boat_orientation_vec))
								# angle between path to traj and boat orientation 			  		
			angle_error = np.arccos(np.dot(boat_orientation_vec, boat_to_traj_hat))
		else:
			rospy.loginfo('Location: Inside orientation radius')
			# Same as above but now we are orienting to the desired final orientation instead of towards the trajectory
			torque_dir = math.copysign(1, np.dot(o_norm, boat_orientation_vec))
								# Angle between traj_orientation and boat orientation
			angle_error = np.arccos(np.dot(boat_orientation_vec, o_hat))

		#rospy.loginfo('enu_angle_to_traj:\t' + str(enu_angle_to_traj * 180 / np.pi))
		#rospy.loginfo('Boat orientation:\t' + str(self.current_orientation[2] * 180 / np.pi))
		#rospy.loginfo('Boat angle to traj\t' + str((boat_angle_to_traj) * 180 / np.pi ))
		

		torque = angle_error * torque_dir * self.p
		force = traj.posetwist.twist.linear.x
		if boat_dist_to_traj < self.orientation_radius and overshoot == -1:
			rospy.loginfo('Status: Overshoot in orientation radius')
			force = force * -1
		elif abs(angle_error) > np.pi / 2:
			rospy.loginfo('Status: angle error > 90')
			force = 0
		else:
			rospy.loginfo('Status: Normal')

		rospy.loginfo('Angle error: ' + str(angle_error * torque_dir * 180 / np.pi))

		rospy.loginfo('torque: ' + str(torque))
		rospy.loginfo('Force: ' + str(force))

		""" Method 1:
		#
		##		P error = - perpendicular_velocity * p_gain * overshoot
		#
		# Velocity error = velocity perpendicular to trajectory orientation
		velocity_error = self.current_velocity - (np.dot(self.current_velocity, o_hat) * o_hat)
		v_dir = np.dot(velocity_error, o_norm)
		velocity_error = math.copysign(np.linalg.norm(velocity_error), v_dir)
		rospy.loginfo('V_perp = ' + str(velocity_error))
		velocity_error = -1 * velocity_error * self.p * overshoot
		rospy.loginfo('P error = ' + str(velocity_error))

		#
		##		I error = - position * i_gain * overshoot * ???
		#
		# Positional error
		#				boat_position		parralel portion of boat position
		pos_error = self.current_position - boat_proj
		p_dir = np.dot(pos_error, o_norm)
		pos_error = math.copysign(np.linalg.norm(pos_error), p_dir)
		rospy.loginfo('Perp_position = ' + str(pos_error))
		pos_error = -1 * pos_error * self.i * overshoot
		rospy.loginfo('I error = ' + str(pos_error))

		#
		##		D error
		#
		# Acceleration error
		acceleration_error = self.d * (velocity_error - self.last_perp_velocity) / dt
		self.last_perp_velocity = velocity_error

		torque = velocity_error + pos_error + acceleration_error


		# Reverse force if overshoot
		force = traj.posetwist.twist.linear.x * overshoot
		rospy.loginfo('torque: ' + str(torque))
		"""

		# Output a wrench!
		if not self.killed:
			self.wrench_pub.publish(
				WrenchStamped(
					header = Header(
						frame_id = '/base_link',
						stamp = now),
					wrench = Wrench(
						force = Vector3(force, 0, 0),
						torque = Vector3(0, 0, torque))))
		else:
			# Publish zero wrench
			self.wrench_pub.publish(WrenchStamped())
示例#25
0
 def event(self):
     mp = list(pg.mouse.get_pos())
     for event in pg.event.get():
         if event.type == pg.QUIT:
             self.running = False
             quit()
         if event.type == pg.MOUSEBUTTONDOWN:
         ### SCROLLING ###
             if event.button == 4:
                 try:
                     if self.left_color < len(self.toolbar.cells)-1:
                         self.left_color += 1
                         self.toolbar.color_l.color = self.toolbar.palette.colors[self.left_color]
                         self.toolbar.update()
                         self.screen.blit(self.toolbar.color_l.image, self.toolbar.color_l)
                         pg.display.update(self.toolbar.area)
                 except TypeError:
                     pass
             if event.button == 5:
                 try:
                     if self.left_color > 0:
                         self.right_color -= 1
                         self.toolbar.color_l.color = self.toolbar.palette.colors[self.left_color]
                         self.toolbar.update()
                         self.screen.blit(self.toolbar.color_l.image, self.toolbar.color_l)
                         pg.display.update(self.toolbar.area)
                 except TypeError:
                     pass
         if event.type == pg.MOUSEMOTION or event.type == pg.MOUSEBUTTONDOWN:
         ### TOOLBAR ###
             # Data
             if self.toolbar.area.rect.collidepoint(mp[0], mp[1]):
                 if pg.mouse.get_pressed() == (1, 0, 0):
                     if not self.working_data:
                         if self.toolbar.button_save.rect.collidepoint(mp[0], mp[1]):
                             print("Enter name to save")
                             name = input(": ")
                             self.working_data = True
                             self.save(name)
                         elif self.toolbar.button_load.rect.collidepoint(mp[0], mp[1]):
                             print("Enter name to load")
                             name = input(": ")
                             self.working_data = True
                             self.load(name)
                         elif self.toolbar.button_export.rect.collidepoint(mp[0], mp[1]):
                             print("Enter name to save")
                             name = input(": ")
                             self.last_save_dir = name
                             self.working_data = True
                             self.port(name, 0)
                         elif self.toolbar.button_import.rect.collidepoint(mp[0], mp[1]):
                             print("Enter name to load")
                             name = input(": ")
                             self.last_save_dir = name
                             self.working_data = True
                             self.port(name, 1)
                     # Set Tool
                         for t in self.toolbar.tools:
                             if t.rect.collidepoint(mp[0], mp[1]):
                                 if t.cursor != None:
                                     self.cursor = t.cursor
                                     cursor = pg.cursors.compile(self.cursor, black='X', white='.', xor='o')
                                     pg.mouse.set_cursor((16, 16), (0, 0), *cursor)
                 # Change Color
                 if self.toolbar.palette_area.rect.collidepoint(mp[0], mp[1]):
                     if pg.mouse.get_pressed() == (1, 0, 0):
                         if not self.working_data:
                             for i, c in enumerate(self.toolbar.cells):
                                 if c.rect.collidepoint(mp[0], mp[1]):
                                     self.left_color = i
                                     self.toolbar.color_l.color = self.toolbar.palette.colors[self.left_color]
                                     self.toolbar.update()
                                     self.screen.blit(self.toolbar.color_l.image, self.toolbar.color_l)
                                     pg.display.update(self.toolbar.area)
                     if pg.mouse.get_pressed() == (0, 0, 1):
                         if not self.working_data:
                             for i, c in enumerate(self.toolbar.cells):
                                 if c.rect.collidepoint(mp[0], mp[1]):
                                     self.right_color = i
                                     self.toolbar.color_r.color = self.toolbar.palette.colors[self.right_color]
                                     self.toolbar.update()
                                     self.screen.blit(self.toolbar.color_r.image, self.toolbar.color_r)
                                     pg.display.update(self.toolbar.area)
         ### CANVAS ###
             # Apply Tool
             if self.canvas_area.rect.collidepoint(mp[0], mp[1]):
                 if pg.mouse.get_pressed() == (1, 0, 0):
                     if not self.working_data:
                         if self.cursor == cursor_norm:
                             tools.select(self, mp)
                         if self.cursor == cursor_draw:
                             tools.draw(self, mp, self.left_color)
                             pg.display.update(self.canvas_area)
                         if self.cursor == cursor_line:
                             self.working_data = True
                             tools.line(self, mp, self.left_color)
                             pg.display.update(self.canvas_area)
                         if self.cursor == cursor_rect:
                             self.working_data = True
                             tools.rect_f(self, mp, self.left_color)
                             pg.display.update(self.canvas_area)
                         if self.cursor == cursor_rcte:
                             self.working_data = True
                             tools.rect_e(self, mp, self.left_color)
                             pg.display.update(self.canvas_area)
                         if self.cursor == cursor_oval:
                             self.working_data = True
                             tools.oval_f(self, mp, self.left_color)
                             pg.display.update(self.canvas_area)
                         if self.cursor == cursor_ovle:
                             self.working_data = True
                             tools.oval_e(self, mp, self.left_color, self.tool_thickness)
                             pg.display.update(self.canvas_area)
                         if self.cursor == cursor_crcl:
                             self.working_data = True
                             tools.circle(self, mp, self.left_color)
                             pg.display.update(self.canvas_area)
                         if self.cursor == cursor_fill:
                             self.working_data = True
                             tools.flood_fill(self, mp, self.left_color)
                             pg.display.update(self.canvas_area)
                         if self.cursor == cursor_pick:
                             self.left_color = tools.dropper(self, mp)
                             self.toolbar.color_l.color = tools.dropper(self, mp)
                             self.screen.blit(self.toolbar.color_l.image, self.toolbar.color_l)
                             pg.display.update(self.toolbar.area)
                 if pg.mouse.get_pressed() == (0, 0, 1):
                     if not self.working_data:
                         if self.cursor == cursor_draw:
                             tools.draw(self, mp, self.right_color)
                             pg.display.update(self.canvas_area)
                         if self.cursor == cursor_line:
                             self.working_data = True
                             tools.line(self, mp, self.right_color)
                             pg.display.update(self.canvas_area)
                         if self.cursor == cursor_rect:
                             self.working_data = True
                             tools.rect_f(self, mp, self.right_color)
                             pg.display.update(self.canvas_area)
                         if self.cursor == cursor_rcte:
                             self.working_data = True
                             tools.rect_e(self, mp, self.right_color)
                             pg.display.update(self.canvas_area)
                         if self.cursor == cursor_oval:
                             self.working_data = True
                             tools.oval_f(self, mp, self.right_color)
                             pg.display.update(self.canvas_area)
                         if self.cursor == cursor_ovle:
                             self.working_data = True
                             tools.oval_e(self, mp, self.right_color, self.tool_thickness)
                             pg.display.update(self.canvas_area)
                         if self.cursor == cursor_crcl:
                             self.working_data = True
                             tools.circle(self, mp, self.right_color)
                             pg.display.update(self.canvas_area)
                         if self.cursor == cursor_fill:
                             self.working_data = True
                             tools.flood_fill(self, mp, self.right_color)
                             pg.display.update(self.canvas_area)
                         if self.cursor == cursor_pick:
                             self.right_color = tools.dropper(self, mp)
                             self.toolbar.color_r.color = tools.dropper(self, mp)
                             self.screen.blit(self.toolbar.color_r.image, self.toolbar.color_r)
                             pg.display.update(self.toolbar.area)
                 # Commit Selection
         if event.type == pg.MOUSEBUTTONUP:
             if self.canvas_area.rect.collidepoint(mp[0], mp[1]):
                 if self.cursor == cursor_norm:
                     if not self.working_data:
                         self.working_data = True
                         tools.set_select(self, mp)
                         for c in self.clipboard['matrix']:
                             c.update()
                             self.screen.blit(c.image, c)
                             pg.display.update(self.canvas_area)
             else:
                 for s in self.toolbar.cells:
                     self.screen.blit(s.image, s)
                 for b in self.toolbar.buttons:
                     self.screen.blit(b.image, b)
                 for t in self.toolbar.tools:
                     self.screen.blit(t.image, t)
                 pg.display.update(self.toolbar.palette_area)
                 pg.display.update(self.toolbar.area)
     ### KEYS ###
         if event.type == pg.KEYDOWN:
             # Rotation
             if event.key == pg.K_KP2:
                 self.rotation = 270
             if event.key == pg.K_KP4:
                 self.rotation = 180
             if event.key == pg.K_KP8:
                 self.rotation = 90
             if event.key == pg.K_KP6:
                 self.rotation = 0
             # Blur
             if event.key == pg.K_b:
                 if not self.working_data:
                     tools.blur(self)
                     pg.display.update(self.canvas_area)
             # Quick Save
             if (event.mod == pg.KMOD_LCTRL or event.mod == pg.KMOD_RCTRL) and event.key == pg.K_s:
                 if not self.working_data:
                     if self.last_save_dir != '':
                         self.working_data = True
                         self.port(self.last_save_dir, 0)
             # Grid
             if (event.mod == pg.KMOD_LCTRL or event.mod == pg.KMOD_RCTRL) and event.key == pg.K_g:
                 self.grid = False
                 for c in self.canvas:
                     self.screen.blit(c.image, c)
                 pg.display.update(self.canvas_area)
                 made_changes = True
             if (event.mod == pg.KMOD_LSHIFT or event.mod == pg.KMOD_RSHIFT) and event.key == pg.K_g:
                 self.grid = True
             # Pasting
             if (event.mod == pg.KMOD_LCTRL or event.mod == pg.KMOD_RCTRL) and event.key == pg.K_v:
                 tools.paste(self, mp)
                 pg.display.update(self.canvas_area)
             if (event.mod == pg.KMOD_LSHIFT or event.mod == pg.KMOD_RSHIFT) and event.key == pg.K_v:
                 tools.paste(self, mp, mode=1)
                 pg.display.update(self.canvas_area)
             # Undo
             if (event.mod == pg.KMOD_LCTRL or event.mod == pg.KMOD_RCTRL) and event.key == pg.K_z:
                 self.undo()
             # Exiting
             if event.key == pg.K_ESCAPE:
                 self.running = False
             # Change Mouse Position
             if mp[1] > 0 and mp[1] < list(self.canvas_size)[1] and mp[0] > 0 and mp[0] < list(self.canvas_size)[0]:
                 if event.key == pg.K_UP:
                     for c in self.canvas:
                         if c.rect.collidepoint(mp[0], mp[1]):
                             pg.mouse.set_pos([c.posx+(CELL_SIZE/2), c.posy+(CELL_SIZE/2)-CELL_SIZE])
                 if event.key == pg.K_DOWN:
                     for c in self.canvas:
                         if c.rect.collidepoint(mp[0], mp[1]):
                             pg.mouse.set_pos([c.posx+(CELL_SIZE/2), c.posy+(CELL_SIZE/2)+CELL_SIZE])
                 if event.key == pg.K_LEFT:
                     for c in self.canvas:
                         if c.rect.collidepoint(mp[0], mp[1]):
                             pg.mouse.set_pos([c.posx+(CELL_SIZE/2)-CELL_SIZE, c.posy+(CELL_SIZE/2)])
                 if event.key == pg.K_RIGHT:
                     for c in self.canvas:
                         if c.rect.collidepoint(mp[0], mp[1]):
                             pg.mouse.set_pos([c.posx+(CELL_SIZE/2)+CELL_SIZE, c.posy+(CELL_SIZE/2)])