def do_part_2(station, data): asteroids = init_asteroids(data) viz = Visualizer((-1, -1, 36, 36), 20, False) for xy in asteroids: viz.draw_point(xy, COLORS[2], 4) grouped_by_angle = defaultdict(list) for location in station.locations_by_angle(asteroids): grouped_by_angle[location.angle].append(location) asteroids_shot = 0 asteroid_200 = None while asteroids_shot < 200: for angle, locations in grouped_by_angle.items(): asteroids_shot += 1 last_asteroid_shot = locations[0].asteroid viz.draw_line((station.xy, last_asteroid_shot.xy), COLORS[1], 2) viz.draw_point(last_asteroid_shot.xy, Color(R=255, G=0, B=0), 4) if asteroids_shot == 200: asteroid_200 = last_asteroid_shot break grouped_by_angle[angle] = locations[1:] viz.draw_point(station.xy, COLORS[0], 10) viz.show() return asteroid_200
def do(data, starting_panel): robot = Robot(data, starting_panel) while not robot.brain.on_fire: robot.step() boundaries = Visualizer.boundaries(robot.painted.keys()) if starting_panel == 1: viz = Visualizer(boundaries, 10) point_size = 5 else: viz = Visualizer(boundaries, 100) point_size = 50 for p, color in robot.painted.items(): if color: viz.draw_square(p, WHITE, point_size) viz.show() return len(robot.painted)
def do_part_2(station, data): viz = Visualizer((0, 0, 36, 36), 20, flip_vertical=False) print(f"\nThe asteroid can see this:") asteroids = init_asteroids(data) asteroids_by_degrees = list() for a in asteroids_by_angle(station, asteroids): asteroids_by_degrees.append((rad_to_deg(a[0]), *a)) # for a in sorted(asteroids_by_degrees): # print(a) sets_by_angle = defaultdict(list) for a in sorted(asteroids_by_degrees): sets_by_angle[a[0]].append(a[3]) for k, v in sets_by_angle.items(): if len(v) > 0: print(k, len(v), v) for a in v: if a.xy == (0, 2): print('^^^^^^^^') asteroids_shot = 0 last_asteroid_shot = None while asteroids_shot < 200: for k, v in sets_by_angle.items(): last_asteroid_shot = v[0] sets_by_angle[k] = v[1:] asteroids_shot += 1 viz.draw_line((station.xy, last_asteroid_shot.xy), COLORS[1], 2) viz.draw_point(last_asteroid_shot.xy, COLORS[2], 4) print( f"Boom, shot asteroid nr. {asteroids_shot}: {last_asteroid_shot}" ) if asteroids_shot == 200: code = last_asteroid_shot.x * 100 + last_asteroid_shot.y print(f"200th asteroid shot is: {last_asteroid_shot}: {code}") break viz.draw_point(station.xy, COLORS[0], 10) viz.show() return 0
import json from visualize import Visualizer, COLORS with open("infi-2019-input.json") as f: data = json.load(f) flats = {k: v for k, v in data['flats']} x, y = data['flats'][0] print(flats) max_x = max(flats.keys()) + 1 max_y = max(flats.values()) + 1 viz = Visualizer((0, 0, max_x, max_y)) for x, y in flats.items(): viz.draw_line(((x, 0), (x, y)), COLORS[0]) viz.show()
# Dataset x_train, x_test, y_train, y_test = iris() # x_train, x_test, y_train, y_test = digits() max_recall = np.zeros([4]) max_c = None fig_x = [x for x in range(-20, 20)] vis = Visualizer(num_x=len(fig_x)) for i, x in enumerate(fig_x): elm = MetricELM(hidden_num=4, c=2**x) elm.fit(x_train, y_train) recall = elm.validation(x_test, y_test) # visualization print("c=", x, "R@{1,2,4,8}:", np.around(recall, decimals=3)) vis.set(i, recall) # record max if recall[0] > max_recall[0]: max_recall = recall max_c = x print('best:') print("c=", max_c, "R@{1,2,4,8}:", np.around(max_recall, decimals=3)) vis.plot(x=fig_x, max_c=max_c, max_recall=max_recall) vis.show() # vis.save('resources/iris.png')
class Prompt(cmd.Cmd): """User interface for profile generation Defines all the commands users can use to generate and work on numerical velocity profiles. Also supplies the command loop structure. Attributes: waypoints : A list of waypoints which define the path path : The path the robot will drive robot : The robot that will have to follow the path visualize : The visualizer which displays the path and profiles profile : The numerical velocity profile """ def __init__(self): self.waypoints = [] self.profile = None self.path = None self.robot = Robot(2, 15, 10) self.visualize = Visualizer(self.path, offset=self.robot.width / 2.) cmd.Cmd.__init__(self) def update_robot(self, attribute, value): """Updates one of the robots attributes Args: attribute: A string representing which value to modify value: A float to be inserted """ if attribute == "width": self.robot.width = value print " Set width to", value, "feet" elif attribute == "velocity": self.robot.velocity = value print " Set velocity to", value, "feet per second" elif attribute == "acceleration": self.robot.acceleration = value print " Set acceleration to", value, "feet per second squared" else: print " Could not recognize attribute:", attribute print " try help robot for more information on this command" def print_attribute(self, attribute): """Prints one of the robots attributes Displays the requested attribute to the console Args: attribute: A string representing one of the robots properties """ if attribute == "width": print " Width:", self.robot.width, "feet" elif attribute == "velocity": print " Velocity:", self.robot.max_velocity, \ "feet per second" elif attribute == "acceleration": print " Acceleration:", self.robot.max_acceleration, \ "feet per second squared" else: print " Could not recognize attribute:", attribute, \ " try help robot for more information on this command" def remove_waypoint(self, index): """Removes a waypoint This is meant to be called by the waypoint remove command. It parses the index into an integer (hopefully) and then removes the waypoint. Args: index: The index of the waypoint to be removed, 0 indexed. """ try: index = int(index) del self.waypoints[index] self.path = from_waypoints(self.waypoints) self.update_path() except ValueError: print " Could not parse", index @staticmethod def parse_vector(vector): """Parses a string into a numpy array Chops off the first and last character and then parses into a numpy array. This results in potentially weird outcomes. Args: vector: A string in the form (1,2,...,n), [1,2,...,n], <1,2,...,n> etc Returns: array: A numpy array Raises: ValueError: If the provided string can not be coerced into an array """ try: return np.fromstring(vector[1, -1], sep=",") except ValueError: raise ValueError("Could not parse: " + vector) def add_waypoint(self, position, velocity, acceleration): """Adds a given waypoint This is meant to be called from the waypoint add command. It parses the input into vectors then adds the waypoint. Args: position (str): Represents the position in 2d space of the waypoint. Should be parsable by :func:`~core.Prompt.parse_vector` velocity (str): Represents the velocity in 2d space of the waypoint. Should be parsable by :func:`~core.Prompt.parse_vector` acceleration (str): Represents the acceleration in 2d space of the waypoint. Should be parsable by :func:`~core.Prompt.parse_vector` """ try: position = self.parse_vector(position) velocity = self.parse_vector(velocity) acceleration = self.parse_vector(acceleration) waypoint = Waypoint(position, velocity, acceleration) print " Adding waypoint:" print waypoint self.waypoints.append(waypoint) self.path = from_waypoints(self.waypoints) except ValueError as err: print err def update_path(self): """Updates and redraws the path""" self.visualize.update_path(self.path, offset=self.robot.width / 2.) def print_waypoints(self): """Prints all of the waypoints.""" if self.waypoints: for waypoint in self.waypoints: print waypoint else: print "No waypoints" @staticmethod def help_waypoint(): """Displays the help text for the waypoint command.""" print " Manipulates the waypoints:" print " waypoint : will list waypoints" print " waypoint remove n : removes the nth waypoint (0 indexed)" print " waypoint add (px,py) (vx,vy) (ay,ax) :",\ " adds waypoint with position (px,py), velocity (vx,vy),",\ " and acceleration (ax,ay)" print " waypoint clear : deletes all waypoints " def do_waypoint(self, args): """Handles user input for waypoint manipulation Allows the user to modify the list of waypoints. The current commands which are accepted are: - waypoint clear : clears all waypoints - waypoint remove n : removes the nth waypoint (0 indexed) handled by :func:`~core.Prompt.remove_waypoint` - waypoint add position velocity acceleration : adds a waypoint with the given position, velocity, and acceleration. handled by :func:`~core.Prompt.add_waypoint` Args: args (str) : A string representing all the text from the users input after 'waypoint' """ if args: args = args.split(' ') else: args = None if args is None: self.print_waypoints() elif args[0] == "clear" and len(args) == 1: del self.waypoints[:] elif args[0] == "remove" and len(args) == 2: self.remove_waypoint(args[1]) elif args[0] == "add" and len(args) == 4: self.add_waypoint(args[1], args[2], args[3]) else: print " Couldn't parse, try help waypoint for more info" self.update_path() @staticmethod def help_robot(): """Displays help text for robot command""" print " Displays and sets robot data:" print " robot : will list all robot attributes" print " robot [attribute] : will display value for [attribute]" print " robot [attribute] x : sets [attribute] to x \n" print " Attributes" print " ==========" print " width : Distance from left wheel to right wheel in feet" print " velocity : Max velocity of robot in feet per second" print " acceleration : Max acceleration of robot",\ " in feet per second squared " def do_robot(self, args): """Handles user input for the robot command Allows the user to manipulate the robot object from the terminal. Accepted user commands at the moment are: - robot : prints the robot object - robot [attribute] : prints the value of the attribute handled by :func:`~core.Prompt.print_attribute` - robot [attribute] [value] : sets the value of attribute to value handled by :func:`~core.Prompt.update_robot` Args: args (str) : A string representing all of the user input after 'robot' """ if args: args = args.split(" ") else: args = None if args is None: print self.robot elif len(args) == 1: attribute = args[0] self.print_attribute(attribute) elif len(args) == 2: attribute = args[0] try: value = float(args[1]) self.update_robot(attribute, value) except ValueError: print " Could not parse:", args[1] else: print " Could not recogize command try \'help robot\' for more information" self.update_path() @staticmethod def help_compute(): """Prints the help text for the compute command""" print " Computes the velocity profile of currently defined path." print " compute ds : ds is the distance between between planning",\ " points in feet" def do_compute(self, args): """Handles the user input to the copmpute command Takes all the waypoints currently defined, the path through them, and the robot and generates a numerical velocity profile. The details of that computation are too long to outline here and are all in the velocity_profile module. Args: args (str) : All the text after the 'compute' will be parsed to a floating number representing the distance between planning points """ if args: try: distance = float(args) self.profile = VelocityProfile(self.path, self.robot, distance) self.visualize.draw_velocity_profile(self.profile) except ValueError: print " Failed to parse", args else: print " Failed to parse, try \'help compute\' for more help" @staticmethod def help_show(): """Prints the help text for the show function.""" print " Displays the plots. If the plots close this won't",\ " reopen them at the moment. That requires embedding",\ " matplotlib graphs in some gui interface and I'm lazy" def do_show(self, args): """Turns on the matplotlib plots Enables the matplotlib plots to render, if any of them are closed this will not reshow them at the moment. I need to work out a better way to handle the plots. """ if args: print "Show does not take arguments" else: self.visualize.show() @staticmethod def help_save(): """Prints the help text for the save command.""" print "Saves the current velocity profile." print " save [name] : saves to name.json" def do_save(self, args): """"Handles user input for the save command Allows the user to save the numerical velocity profile to a json file. At the moment it's very dumb and just dumps it out into same file where this one is located. Moreover it assumes everything after the word 'save' is the of the output file. Args: args (str) : A string representing all of the user input after 'save' """ if args: name = args + ".json" else: name = "profile.jsoin" print "saving to", name with open(name, 'w') as output: json.dump(self.profile, output, cls=ProfileEncoder) @staticmethod def help_intro(): """Prints a short tutorial on how to use the command prompt interface""" print "If you some how stumbled upon this program and don't know", \ "what it is, details can be found here:", \ " https://github.com/iqzprvagbv/path-planning/ \n" print "Here's a quick tl;dr on the workflow in this program:" print "Set the robot parameters width, maximum velocity, and", \ " acceleration using \'robot [parameter] [value]\'\n" print "Add waypoints using the commands \'waypoint position", \ " velocity accel\' If the command show is run before this", \ " you will be able to see the path in realtime. Fixing",\ " mistakes can be done with \'waypoint remove n\'\n" print "Compute the numerical velocity profile with the command",\ " \'compute ds\' where ds is the distance between planning",\ " points\n" print "If the plots look acceptable save the profile using \'",\ "save profile_name\' which will save the file to ",\ "profile_name.json\n" print "The command 'clear' will reset everything but the robot ",\ "and let you plot again, \'quit\' closes the program, and ",\ "\'help [command]\' will display help text and options for ",\ "every command. Enjoy." @staticmethod def do_quit(line): """Quits the program""" if line: print "Quit does not take any arguments" return True