def initialize_chooser(self, tm): if self.chooser is None: self.chooser = ChooserControl('Autonomous Mode') self.choices = self.chooser.getChoices() if len(self.choices) == 0: return False self.state = 'disabled' self.currentChoice = -1 self.until = tm self.init_time = tm self.initialized = True return True
def test_chooser_control(nt): c = ChooserControl('Autonomous Mode') assert c.getChoices() == () assert c.getSelected() is None c.setSelected("foo") assert c.getSelected() == 'foo' t = nt.getTable('/SmartDashboard/Autonomous Mode') assert t.getString('selected', None) == 'foo' t.putStringArray('options', ('option1', 'option2')) assert c.getChoices() == ('option1', 'option2')
def test_chooser_control(nt): c = ChooserControl("Autonomous Mode", inst=nt) assert c.getChoices() == () assert c.getSelected() is None c.setSelected("foo") assert c.getSelected() == "foo" t = nt.getTable("/SmartDashboard/Autonomous Mode") assert t.getString("selected", None) == "foo" t.putStringArray("options", ("option1", "option2")) assert c.getChoices() == ("option1", "option2")
import time from networktables import NetworkTables from networktables.util import ChooserControl # To see messages from networktables, you must setup logging import logging logging.basicConfig(level=logging.DEBUG) if len(sys.argv) != 2: print("Error: specify an IP to connect to!") exit(0) ip = sys.argv[1] NetworkTables.initialize(server=ip) def on_choices(value): print("OnChoices", value) def on_selected(value): print("OnSelected", value) cc = ChooserControl("Autonomous Mode", on_choices, on_selected) while True: time.sleep(1)
def _setup_widgets(self, frame): top = tk.Frame(frame) top.grid(column=0, row=0) bottom = tk.Frame(frame) bottom.grid(column=0, row=1) self.field = RobotField(frame, self.manager, self.config_obj) self.field.grid(column=1, row=0, rowspan=2) # status bar self.status = tk.Label(frame, bd=1, relief=tk.SUNKEN, anchor=tk.E) self.status.grid(column=0, row=2, columnspan=2, sticky=tk.W + tk.E) # analog slot = tk.LabelFrame(top, text='Analog') self.analog = [] for i in range(len(hal_data['analog_in'])): if hal_data['analog_in'][i]['initialized'] or hal_data[ 'analog_out'][i]['initialized']: label = tk.Label(slot, text=str(i)) label.grid(column=0, row=i + 1) vw = ValueWidget(slot, clickable=True, minval=-10.0, maxval=10.0) vw.grid(column=1, row=i + 1) self.set_tooltip(vw, 'analog', i) else: vw = None self.analog.append(vw) slot.pack(side=tk.LEFT, fill=tk.Y, padx=5) # digital slot = tk.LabelFrame(top, text='Digital') label = tk.Label(slot, text='PWM') label.grid(column=0, columnspan=4, row=0) self.pwm = [] for i in range(len(hal_data['pwm'])): if hal_data['pwm'][i]['initialized']: c = i // 10 label = tk.Label(slot, text=str(i)) label.grid(column=0 + 2 * c, row=1 + i % 10) vw = ValueWidget(slot) vw.grid(column=1 + 2 * c, row=1 + i % 10) self.set_tooltip(vw, 'pwm', i) else: vw = None self.pwm.append(vw) label = tk.Label(slot, text='Digital I/O') label.grid(column=4, columnspan=6, row=0) self.dio = [] for i in range(len(hal_data['dio'])): if hal_data['dio'][i]['initialized']: c = i // 9 label = tk.Label(slot, text=str(i)) label.grid(column=4 + c * 2, row=1 + i % 9) pi = PanelIndicator(slot, clickable=True) pi.grid(column=5 + c * 2, row=1 + i % 9) self.set_tooltip(pi, 'dio', i) else: pi = None self.dio.append(pi) label = tk.Label(slot, text='Relay') label.grid(column=10, columnspan=2, row=0, padx=5) self.relays = [] for i in range(len(hal_data['relay'])): if hal_data['relay'][i]['initialized']: label = tk.Label(slot, text=str(i)) label.grid(column=10, row=1 + i, sticky=tk.E) pi = PanelIndicator(slot) pi.grid(column=11, row=1 + i) self.set_tooltip(pi, 'relay', i) else: pi = None self.relays.append(pi) slot.pack(side=tk.LEFT, fill=tk.Y, padx=5) csfm = tk.Frame(top) # solenoid slot = tk.LabelFrame(csfm, text='Solenoid') self.solenoids = [] for i in range(len(hal_data['solenoid'])): label = tk.Label(slot, text=str(i)) c = int(i / 2) * 2 r = i % 2 label.grid(column=0 + c, row=r) pi = PanelIndicator(slot) pi.grid(column=1 + c, row=r) self.set_tooltip(pi, 'solenoid', i) self.solenoids.append(pi) slot.pack(side=tk.TOP, fill=tk.BOTH, padx=5) # CAN # self.can_slot = tk.LabelFrame(csfm, text='CAN') # self.can_slot.pack(side=tk.LEFT, fill=tk.BOTH, expand=1, padx=5) # self.can_mode_map = {} # tsrxc.kMode_CurrentCloseLoop: 'PercentVbus', # tsrxc.kMode_DutyCycle:'PercentVbus', # tsrxc.kMode_NoDrive:'Disabled', # tsrxc.kMode_PositionCloseLoop:'Position', # tsrxc.kMode_SlaveFollower:'Follower', # tsrxc.kMode_VelocityCloseLoop:'Speed', # tsrxc.kMode_VoltCompen:'Voltage' # } self.can = {} # detect new devices # for k in sorted(hal_data['CAN'].keys()): # self._add_CAN(k, hal_data['CAN'][k]) csfm.pack(side=tk.LEFT, fill=tk.Y) # joysticks slot = tk.LabelFrame(bottom, text='Joysticks') self.joysticks = [] for i in range(4): axes = [] buttons = [] col = 1 + i * 3 row = 0 label = tk.Label(slot, text='Stick %s' % i) label.grid(column=col, columnspan=3, row=row) row += 1 # TODO: make this configurable for j, t in enumerate(['X', 'Y', 'Z', 'T', '4', '5']): label = tk.Label(slot, text=t) label.grid(column=col, row=row) vw = ValueWidget(slot, clickable=True, default=0.0) vw.grid(column=col + 1, row=row, columnspan=2) self.set_joy_tooltip(vw, i, 'axes', t) axes.append(vw) row += 1 # POV: this needs improvement label = tk.Label(slot, text='POV') label.grid(column=col, row=row) pov = ValueWidget(slot, clickable=True, default=-1, minval=-1, maxval=360, step=45, round_to_step=True) pov.grid(column=col + 1, row=row, columnspan=2) row += 1 for j in range(1, 11): var = tk.IntVar() ck = tk.Checkbutton(slot, text=str(j), variable=var) ck.grid(column=col + 1 + (1 - j % 2), row=row + int((j - 1) / 2)) self.set_joy_tooltip(ck, i, 'buttons', j) buttons.append((ck, var)) self.joysticks.append((axes, buttons, [pov])) slot.pack(side=tk.LEFT, fill=tk.Y, padx=5) ctrl_frame = tk.Frame(bottom) # timing control timing_control = tk.LabelFrame(ctrl_frame, text='Time') def _set_realtime(): if realtime_mode.get() == 0: step_button.pack_forget() step_entry.pack_forget() self.on_pause(False) else: step_button.pack(fill=tk.X) step_entry.pack() self.on_pause(True) realtime_mode = tk.IntVar() button = tk.Radiobutton(timing_control, text='Run', variable=realtime_mode, value=0, command=_set_realtime) button.pack(fill=tk.X) button = tk.Radiobutton(timing_control, text='Pause', variable=realtime_mode, value=1, command=_set_realtime) button.pack(fill=tk.X) step_button = tk.Button(timing_control, text='Step', command=self.on_step_time) self.step_entry = tk.StringVar() self.step_entry.set("0.025") step_entry = tk.Entry(timing_control, width=6, textvariable=self.step_entry) Tooltip.create(step_button, 'Click this to increment time by the step value') Tooltip.create(step_entry, 'Time to step (in seconds)') realtime_mode.set(0) timing_control.pack(side=tk.TOP, fill=tk.BOTH, expand=1) # simulation control sim = tk.LabelFrame(ctrl_frame, text='Robot') self.state_buttons = [] self.mode = tk.IntVar() def _set_mode(): self.manager.set_mode(self.mode.get()) button = tk.Radiobutton(sim, text='Disabled', variable=self.mode, \ value=self.manager.MODE_DISABLED, command=_set_mode) button.pack(fill=tk.X) self.state_buttons.append(button) button = tk.Radiobutton(sim, text='Autonomous', variable=self.mode, \ value=self.manager.MODE_AUTONOMOUS, command=_set_mode) button.pack(fill=tk.X) self.state_buttons.append(button) button = tk.Radiobutton(sim, text='Teleoperated', variable=self.mode, \ value=self.manager.MODE_OPERATOR_CONTROL, command=_set_mode) button.pack(fill=tk.X) self.state_buttons.append(button) button = tk.Radiobutton(sim, text='Test', variable=self.mode, \ value=self.manager.MODE_TEST, command=_set_mode) button.pack(fill=tk.X) self.state_buttons.append(button) self.robot_dead = tk.Label(sim, text='Robot died!', fg='red') sim.pack(side=tk.TOP, fill=tk.BOTH, expand=1) # # Set up a combo box that allows you to select an autonomous # mode in the simulator # try: from tkinter.ttk import Combobox except: pass else: auton = tk.LabelFrame(ctrl_frame, text='Autonomous') self.autobox = Combobox(auton, state='readonly') self.autobox.bind('<<ComboboxSelected>>', self.on_auton_selected) self.autobox['width'] = 12 self.autobox.pack(fill=tk.X) Tooltip.create( self.autobox, "Use robotpy_ext.autonomous.AutonomousModeSelector to use this selection box" ) from networktables.util import ChooserControl self.auton_ctrl = ChooserControl( 'Autonomous Mode', lambda v: self.idle_add(self.on_auton_choices, v), lambda v: self.idle_add(self.on_auton_selection, v)) auton.pack(side=tk.TOP) ctrl_frame.pack(side=tk.LEFT, fill=tk.Y)
def _setup_widgets(self, frame): top = tk.Frame(frame) top.grid(column=0, row=0) bottom = tk.Frame(frame) bottom.grid(column=0, row=1) self.field = RobotField(frame, self.manager, self.config_obj) self.field.grid(column=1, row=0, rowspan=2) # status bar self.status = tk.Label(frame, bd=1, relief=tk.SUNKEN, anchor=tk.E) self.status.grid(column=0, row=2, columnspan=2, sticky=tk.W + tk.E) # analog slot = tk.LabelFrame(top, text="Analog") self.analog = [] for i in range(len(hal_data["analog_in"])): if (hal_data["analog_in"][i]["initialized"] or hal_data["analog_out"][i]["initialized"]): label = tk.Label(slot, text=str(i)) label.grid(column=0, row=i + 1) vw = ValueWidget(slot, clickable=True, minval=-10.0, maxval=10.0) vw.grid(column=1, row=i + 1) self.set_tooltip(vw, "analog", i) else: vw = None self.analog.append(vw) slot.pack(side=tk.LEFT, fill=tk.Y, padx=5) # digital slot = tk.LabelFrame(top, text="Digital") label = tk.Label(slot, text="PWM") label.grid(column=0, columnspan=4, row=0) self.pwm = [] for i in range(len(hal_data["pwm"])): if hal_data["pwm"][i]["initialized"]: c = i // 10 label = tk.Label(slot, text=str(i)) label.grid(column=0 + 2 * c, row=1 + i % 10) vw = ValueWidget(slot) vw.grid(column=1 + 2 * c, row=1 + i % 10) self.set_tooltip(vw, "pwm", i) else: vw = None self.pwm.append(vw) label = tk.Label(slot, text="Digital I/O") label.grid(column=4, columnspan=6, row=0) self.dio = [] for i in range(len(hal_data["dio"])): if hal_data["dio"][i]["initialized"]: c = i // 9 label = tk.Label(slot, text=str(i)) label.grid(column=4 + c * 2, row=1 + i % 9) pi = PanelIndicator(slot, clickable=True) pi.grid(column=5 + c * 2, row=1 + i % 9) self.set_tooltip(pi, "dio", i) else: pi = None self.dio.append(pi) label = tk.Label(slot, text="Relay") label.grid(column=10, columnspan=2, row=0, padx=5) self.relays = [] for i in range(len(hal_data["relay"])): if hal_data["relay"][i]["initialized"]: label = tk.Label(slot, text=str(i)) label.grid(column=10, row=1 + i, sticky=tk.E) pi = PanelIndicator(slot) pi.grid(column=11, row=1 + i) self.set_tooltip(pi, "relay", i) else: pi = None self.relays.append(pi) slot.pack(side=tk.LEFT, fill=tk.Y, padx=5) self.csfm = csfm = tk.Frame(top) # solenoid (pcm) self.pcm = {} # values self.values = {} # CAN self.can_slot = tk.LabelFrame(csfm, text="CAN") self.can_slot.pack(side=tk.LEFT, fill=tk.BOTH, expand=1, padx=5) self.can = {} csfm.pack(side=tk.LEFT, fill=tk.Y) # joysticks slot = tk.LabelFrame(bottom, text="Joysticks") self.joysticks = [] for i in range(4): axes = [] buttons = [] col = 1 + i * 3 row = 0 label = tk.Label(slot, text="Stick %s" % i) label.grid(column=col, columnspan=3, row=row) row += 1 # TODO: make this configurable for j, t in enumerate(["X", "Y", "Z", "T", "4", "5"]): label = tk.Label(slot, text=t) label.grid(column=col, row=row) vw = ValueWidget(slot, clickable=True, default=0.0) vw.grid(column=col + 1, row=row, columnspan=2) self.set_joy_tooltip(vw, i, "axes", t) axes.append(vw) row += 1 # POV: this needs improvement label = tk.Label(slot, text="POV") label.grid(column=col, row=row) pov = ValueWidget( slot, clickable=True, default=-1, minval=-1, maxval=360, step=45, round_to_step=True, ) pov.grid(column=col + 1, row=row, columnspan=2) row += 1 for j in range(1, 11): var = tk.IntVar() ck = tk.Checkbutton(slot, text=str(j), variable=var) ck.grid(column=col + 1 + (1 - j % 2), row=row + int((j - 1) / 2)) self.set_joy_tooltip(ck, i, "buttons", j) buttons.append((ck, var)) self.joysticks.append((axes, buttons, [pov])) slot.pack(side=tk.LEFT, fill=tk.Y, padx=5) ctrl_frame = tk.Frame(bottom) # timing control timing_control = tk.LabelFrame(ctrl_frame, text="Time") def _set_realtime(): if realtime_mode.get() == 0: step_button.pack_forget() step_entry.pack_forget() self.on_pause(False) else: step_button.pack(fill=tk.X) step_entry.pack() self.on_pause(True) realtime_mode = tk.IntVar() button = tk.Radiobutton( timing_control, text="Run", variable=realtime_mode, value=0, command=_set_realtime, ) button.pack(fill=tk.X) button = tk.Radiobutton( timing_control, text="Pause", variable=realtime_mode, value=1, command=_set_realtime, ) button.pack(fill=tk.X) step_button = tk.Button(timing_control, text="Step", command=self.on_step_time) self.step_entry = tk.StringVar() self.step_entry.set("0.025") step_entry = tk.Entry(timing_control, width=6, textvariable=self.step_entry) Tooltip.create(step_button, "Click this to increment time by the step value") Tooltip.create(step_entry, "Time to step (in seconds)") realtime_mode.set(0) timing_control.pack(side=tk.TOP, fill=tk.BOTH, expand=1) # simulation control sim = tk.LabelFrame(ctrl_frame, text="Robot") self.state_buttons = [] self.mode = tk.IntVar() def _set_mode(): self.manager.set_mode(self.mode.get()) button = tk.Radiobutton( sim, text="Disabled", variable=self.mode, value=self.manager.MODE_DISABLED, command=_set_mode, ) button.pack(fill=tk.X) self.state_buttons.append(button) button = tk.Radiobutton( sim, text="Autonomous", variable=self.mode, value=self.manager.MODE_AUTONOMOUS, command=_set_mode, ) button.pack(fill=tk.X) self.state_buttons.append(button) button = tk.Radiobutton( sim, text="Teleoperated", variable=self.mode, value=self.manager.MODE_OPERATOR_CONTROL, command=_set_mode, ) button.pack(fill=tk.X) self.state_buttons.append(button) button = tk.Radiobutton( sim, text="Test", variable=self.mode, value=self.manager.MODE_TEST, command=_set_mode, ) button.pack(fill=tk.X) self.state_buttons.append(button) self.robot_dead = tk.Label(sim, text="Robot died!", fg="red") sim.pack(side=tk.TOP, fill=tk.BOTH, expand=1) # # Set up a combo box that allows you to select an autonomous # mode in the simulator # try: from tkinter.ttk import Combobox except: pass else: auton = tk.LabelFrame(ctrl_frame, text="Autonomous") self.autobox = Combobox(auton, state="readonly") self.autobox.bind("<<ComboboxSelected>>", self.on_auton_selected) self.autobox["width"] = 12 self.autobox.pack(fill=tk.X) Tooltip.create( self.autobox, "Use robotpy_ext.autonomous.AutonomousModeSelector to use this selection box", ) from networktables.util import ChooserControl self.auton_ctrl = ChooserControl( "Autonomous Mode", lambda v: self.idle_add(self.on_auton_choices, v), lambda v: self.idle_add(self.on_auton_selection, v), ) auton.pack(side=tk.TOP) messages = self.config_obj["pyfrc"]["game_specific_messages"] if messages: gamedata = tk.LabelFrame(ctrl_frame, text="Game Data") self.gamedataval = tk.StringVar() if hasattr(self.gamedataval, "trace_add"): self.gamedataval.trace_add("write", self.on_gamedata_selected) else: self.gamedataval.trace_variable("w", self.on_gamedata_selected) self.gamedatabox = Combobox(gamedata, textvariable=self.gamedataval) self.gamedatabox["width"] = 12 self.gamedatabox.pack(fill=tk.X) self.gamedatabox["values"] = messages self.gamedatabox.current(0) self.manager.game_specific_message = self.gamedatabox.get() Tooltip.create( self.gamedatabox, "Use this selection box to simulate game specific data", ) gamedata.pack(side=tk.TOP) def _reset_robot(): for robot in self.manager.robots: robot.physics_controller.reset_position() button = tk.Button(ctrl_frame, text="Reset Robot", command=_reset_robot) button.pack(side=tk.TOP) ctrl_frame.pack(side=tk.LEFT, fill=tk.Y)