def main(): """Fabrication runner, sets conf, reads json input and runs fabrication process.""" ############################################################################ # Docker setup # ############################################################################ ip = {"ROBOT_IP": ROBOT_IPS[fab_conf["target"].as_str()]} compose_up(DOCKER_COMPOSE_PATHS["driver"], check_output=True, env_vars=ip) log.debug("Driver services are running.") ############################################################################ # Load fabrication data # ############################################################################ fab_json_path = fab_conf["paths"]["fab_data_path"].as_path() clay_bullets = load_bullets(fab_json_path) log.info("Fabrication data read from: {}".format(fab_json_path)) log.info("{} items in clay_bullets.".format(len(clay_bullets))) pick_station_json = fab_conf["paths"]["pick_conf_path"].as_path() with pick_station_json.open(mode="r") as fp: pick_station_data = json.load(fp) pick_station = PickStation.from_data(pick_station_data) ############################################################################ # Create Ros Client # ############################################################################ ros = RosClient() ############################################################################ # Create ABB Client # ############################################################################ abb = AbbClient(ros) abb.run() log.debug("Connected to ROS") check_reconnect( abb, driver_container_name=DRIVER_CONTAINER_NAME, timeout_ping=fab_conf["docker"]["timeout_ping"].get(), wait_after_up=fab_conf["docker"]["sleep_after_up"].get(), ) ############################################################################ # setup in_progress JSON # ############################################################################ if not fab_conf["skip_progress_file"]: json_progress_identifier = "IN_PROGRESS-" if fab_json_path.name.startswith(json_progress_identifier): in_progress_json = fab_json_path else: in_progress_json = fab_json_path.with_name( json_progress_identifier + fab_json_path.name) ############################################################################ # Fabrication loop # ############################################################################ to_place = setup_fab_data(clay_bullets) if not questionary.confirm("Ready to start program?").ask(): log.critical("Program exited because user didn't confirm start.") print("Exiting.") sys.exit() # Set speed, accel, tool, wobj and move to start pos pre_procedure(abb) for bullet in to_place: bullet.placed = None bullet.cycle_time = None for i, bullet in enumerate(to_place): current_bullet_desc = "Bullet {:03}/{:03} with id {}.".format( i, len(to_place) - 1, bullet.bullet_id) abb.send(PrintText(current_bullet_desc)) log.info(current_bullet_desc) pick_frame = pick_station.get_next_frame(bullet) # Pick bullet pick_future = pick_bullet(abb, pick_frame) # Place bullet place_future = place_bullet(abb, bullet) bullet.placed = 1 # set placed to temporary value to mark it as "placed" # Write progress to json while waiting for robot if not fab_conf["skip_progress_file"].get(): with in_progress_json.open(mode="w") as fp: json.dump(clay_bullets, fp, cls=ClayBulletEncoder) log.debug("Wrote clay_bullets to {}".format(in_progress_json.name)) # This blocks until cycle is finished cycle_time = pick_future.result() + place_future.result() bullet.cycle_time = cycle_time log.debug("Cycle time was {}".format(bullet.cycle_time)) bullet.placed = time.time() log.debug("Time placed was {}".format(bullet.placed)) ############################################################################ # Shutdown procedure # ############################################################################ # Write progress of last run of loop if not fab_conf["skip_progress_file"].get(): with in_progress_json.open(mode="w") as fp: json.dump(clay_bullets, fp, cls=ClayBulletEncoder) log.debug("Wrote clay_bullets to {}".format(in_progress_json.name)) if (len([bullet for bullet in clay_bullets if bullet.placed is None]) == 0 and not fab_conf["skip_progress_file"].get()): done_file_name = fab_json_path.name.replace(json_progress_identifier, "") done_json = fab_conf["paths"]["json_dir"].as_path( ) / "00_done" / done_file_name in_progress_json.rename(done_json) with done_json.open(mode="w") as fp: json.dump(clay_bullets, fp, cls=ClayBulletEncoder) log.debug("Saved placed bullets to 00_Done.") elif not fab_conf["skip_progress_file"].get(): log.debug("Bullets without placed timestamp still present, keeping {}". format(in_progress_json.name)) log.info("Finished program with {} bullets.".format(len(to_place))) post_procedure(abb)
def std_move_to_frame( frame, tool="tool0", wobj="wobj0", motion_type=Motion.LINEAR, speed=200, accel=100, zone=Zone.FINE, timeout=None, ): """Move robot arm to target or targets. Parameters ---------- frame : :class:`compas.geometry.Frame` or :obj:`list` of :class:`compas.geometry.Frame` Target frame or frames. tool : :obj:`str` Name of tool as named in RAPID code on controller to use for TCP data. wobj : :obj:`str` Name of work object as named in RAPID code on controller to use for coordinate system. motion_type : :class:`compas_rrc.Motion` Motion type, either linear (:class:`~compas_rrc.Motion.LINEAR`) or joint (:class:`~compas_rrc.Motion.JOINT`). speed : :obj:`float` TCP speed in mm/s. Limited by hard coded max speed in this function as well as safety systems on controller. accel : :obj:`float` Acceleration in percentage of standard acceleration. zone : :class:`compas_rrc.Zone` Set zone value of movement, (acceptable deviation from target). timeout : :obj:`float` Time to wait for indication of finished movement. If not defined no feedback will be requested. """ # noqa: E501 if not isinstance(frame, Sequence): frames = [frame] else: frames = frame with RosClient() as ros: # Create ABB Client abb = AbbClient(ros) abb.run(timeout=5) abb.send(SetTool(tool)) abb.send(SetWorkObject(wobj)) # Set acceleration data ramp = 100 # % Higher values makes the acceleration ramp longer abb.send(SetAcceleration(accel, ramp)) # Set speed override and max speed speed_override = 100 # % max_tcp_speed = 500 # mm/s abb.send(SetMaxSpeed(speed_override, max_tcp_speed)) # Move to Frame for f in frames: abb.send( PrintText(" Moving to {:.3f}, {:.3f}, {:.3f}.".format( *f.point.data))) abb.send(MoveToFrame(f, speed, zone, motion_type)) if timeout: abb.send_and_wait(Noop(), timeout=timeout)