class Color(PluginBase): def __init__(self, *args): super().__init__(BrickletColor, *args) self.color = self.device self.cbe_color = CallbackEmulator( self, self.color.get_color, None, self.cb_color, self.increase_error_count, expand_result_tuple_for_callback=True) self.cbe_illuminance = CallbackEmulator(self, self.color.get_illuminance, None, self.cb_illuminance, self.increase_error_count) self.cbe_color_temperature = CallbackEmulator( self, self.color.get_color_temperature, None, self.cb_color_temperature, self.increase_error_count) self.color_frame = ColorFrame(25, 25, QColor(128, 128, 128)) self.illuminance_frame = ColorFrame(25, 25, QColor(128, 128, 128)) self.color_temperature_frame = ColorFrame(25, 25, QColor(128, 128, 128)) self.current_color_r = CurveValueWrapper() # int self.current_color_g = CurveValueWrapper() # int self.current_color_b = CurveValueWrapper() # int self.current_color_c = CurveValueWrapper() # int self.current_illuminance = CurveValueWrapper() # float, lx self.current_color_temperature = CurveValueWrapper() # int, K self.clear_graphs_button = QPushButton("Clear Graphs") plots = [('R', Qt.red, self.current_color_r, lambda value: self.format_color(0, value)), ('G', Qt.darkGreen, self.current_color_g, lambda value: self.format_color(1, value)), ('B', Qt.blue, self.current_color_b, lambda value: self.format_color(2, value)), ('C', Qt.black, self.current_color_c, str)] self.plot_widget = PlotWidget('Color', plots, clear_button=self.clear_graphs_button, extra_key_widgets=[self.color_frame], y_resolution=1.0) self.plot_widget.setMinimumSize(250, 200) plots_illuminance = [('Illuminance', Qt.red, self.current_illuminance, '{} lx (Lux)'.format)] self.plot_widget_illuminance = PlotWidget( 'Illuminance [lx]', plots_illuminance, clear_button=self.clear_graphs_button, extra_key_widgets=[self.illuminance_frame], y_resolution=0.1) self.plot_widget_illuminance.setMinimumSize(250, 200) plots_color_temperature = [ ('Color Temperature', Qt.red, self.current_color_temperature, '{} K'.format) ] self.plot_widget_color_temperature = PlotWidget( 'Color Temperature [K]', plots_color_temperature, clear_button=self.clear_graphs_button, extra_key_widgets=[self.color_temperature_frame], y_resolution=1.0) self.plot_widget_color_temperature.setMinimumSize(250, 200) self.gain_label = QLabel('Gain:') self.gain_combo = QComboBox() self.gain_combo.addItem("1x") self.gain_combo.addItem("4x") self.gain_combo.addItem("16x") self.gain_combo.addItem("60x") self.gain_combo.currentIndexChanged.connect(self.gain_changed) self.current_gain_factor = 60 self.conversion_label = QLabel('Integration Time:') self.conversion_combo = QComboBox() self.conversion_combo.addItem("2.4 ms") self.conversion_combo.addItem("24 ms") self.conversion_combo.addItem("101 ms") self.conversion_combo.addItem("154 ms") self.conversion_combo.addItem("700 ms") self.current_conversion_time = 154 self.conversion_combo.currentIndexChanged.connect( self.conversion_changed) self.light_checkbox = QCheckBox("Enable Light") self.light_checkbox.stateChanged.connect(self.light_state_changed) layout_h1 = QHBoxLayout() layout_h1.addWidget(self.plot_widget_illuminance) layout_h1.addWidget(self.plot_widget_color_temperature) layout_h2 = QHBoxLayout() layout_h2.addWidget(self.gain_label) layout_h2.addWidget(self.gain_combo) layout_h2.addWidget(self.conversion_label) layout_h2.addWidget(self.conversion_combo) layout_h2.addWidget(self.light_checkbox) layout_h2.addStretch() layout_h2.addWidget(self.clear_graphs_button) line1 = QFrame() line1.setObjectName("line1") line1.setFrameShape(QFrame.HLine) line1.setFrameShadow(QFrame.Sunken) line2 = QFrame() line2.setObjectName("line2") line2.setFrameShape(QFrame.HLine) line2.setFrameShadow(QFrame.Sunken) layout = QVBoxLayout(self) layout.addWidget(self.plot_widget) layout.addWidget(line1) layout.addLayout(layout_h1) layout.addWidget(line2) layout.addLayout(layout_h2) self.k_to_rgb = { 1000: (255, 56, 0), 1100: (255, 71, 0), 1200: (255, 83, 0), 1300: (255, 93, 0), 1400: (255, 101, 0), 1500: (255, 109, 0), 1600: (255, 115, 0), 1700: (255, 121, 0), 1800: (255, 126, 0), 1900: (255, 131, 0), 2000: (255, 137, 18), 2100: (255, 142, 33), 2200: (255, 147, 44), 2300: (255, 152, 54), 2400: (255, 157, 63), 2500: (255, 161, 72), 2600: (255, 165, 79), 2700: (255, 169, 87), 2800: (255, 173, 94), 2900: (255, 177, 101), 3000: (255, 180, 107), 3100: (255, 184, 114), 3200: (255, 187, 120), 3300: (255, 190, 126), 3400: (255, 193, 132), 3500: (255, 196, 137), 3600: (255, 199, 143), 3700: (255, 201, 148), 3800: (255, 204, 153), 3900: (255, 206, 159), 4000: (255, 209, 163), 4100: (255, 211, 168), 4200: (255, 213, 173), 4300: (255, 215, 177), 4400: (255, 217, 182), 4500: (255, 219, 186), 4600: (255, 221, 190), 4700: (255, 223, 194), 4800: (255, 225, 198), 4900: (255, 227, 202), 5000: (255, 228, 206), 5100: (255, 230, 210), 5200: (255, 232, 213), 5300: (255, 233, 217), 5400: (255, 235, 220), 5500: (255, 236, 224), 5600: (255, 238, 227), 5700: (255, 239, 230), 5800: (255, 240, 233), 5900: (255, 242, 236), 6000: (255, 243, 239), 6100: (255, 244, 242), 6200: (255, 245, 245), 6300: (255, 246, 248), 6400: (255, 248, 251), 6500: (255, 249, 253), 6600: (254, 249, 255), 6700: (252, 247, 255), 6800: (249, 246, 255), 6900: (247, 245, 255), 7000: (245, 243, 255), 7100: (243, 242, 255), 7200: (240, 241, 255), 7300: (239, 240, 255), 7400: (237, 239, 255), 7500: (235, 238, 255), 7600: (233, 237, 255), 7700: (231, 236, 255), 7800: (230, 235, 255), 7900: (228, 234, 255), 8000: (227, 233, 255), 8100: (225, 232, 255), 8200: (224, 231, 255), 8300: (222, 230, 255), 8400: (221, 230, 255), 8500: (220, 229, 255), 8600: (218, 228, 255), 8700: (217, 227, 255), 8800: (216, 227, 255), 8900: (215, 226, 255), 9000: (214, 225, 255), 9100: (212, 225, 255), 9200: (211, 224, 255), 9300: (210, 223, 255), 9400: (209, 223, 255), 9500: (208, 222, 255), 9600: (207, 221, 255), 9700: (207, 221, 255), 9800: (206, 220, 255), 9900: (205, 220, 255), 10000: (204, 219, 255), 10100: (203, 219, 255), 10200: (202, 218, 255), 10300: (201, 218, 255), 10400: (201, 217, 255), 10500: (200, 217, 255), 10600: (199, 216, 255), 10700: (199, 216, 255), 10800: (198, 216, 255), 10900: (197, 215, 255), 11000: (196, 215, 255), 11100: (196, 214, 255), 11200: (195, 214, 255), 11300: (195, 214, 255), 11400: (194, 213, 255), 11500: (193, 213, 255), 11600: (193, 212, 255), 11700: (192, 212, 255), 11800: (192, 212, 255), 11900: (191, 211, 255), 12000: (191, 211, 255), 12100: (190, 211, 255), 12200: (190, 210, 255), 12300: (189, 210, 255), 12400: (189, 210, 255), 12500: (188, 210, 255), 12600: (188, 209, 255), 12700: (187, 209, 255), 12800: (187, 209, 255), 12900: (186, 208, 255), 13000: (186, 208, 255), 13100: (185, 208, 255), 13200: (185, 208, 255), 13300: (185, 207, 255), 13400: (184, 207, 255), 13500: (184, 207, 255), 13600: (183, 207, 255), 13700: (183, 206, 255), 13800: (183, 206, 255), 13900: (182, 206, 255), 14000: (182, 206, 255), 14100: (182, 205, 255), 14200: (181, 205, 255), 14300: (181, 205, 255), 14400: (181, 205, 255), 14500: (180, 205, 255), 14600: (180, 204, 255), 14700: (180, 204, 255), 14800: (179, 204, 255), 14900: (179, 204, 255), 15000: (179, 204, 255), 15100: (178, 203, 255), 15200: (178, 203, 255), 15300: (178, 203, 255), 15400: (178, 203, 255), 15500: (177, 203, 255), 15600: (177, 202, 255), 15700: (177, 202, 255), 15800: (177, 202, 255), 15900: (176, 202, 255), 16000: (176, 202, 255), 16100: (176, 202, 255), 16200: (175, 201, 255), 16300: (175, 201, 255), 16400: (175, 201, 255), 16500: (175, 201, 255), 16600: (175, 201, 255), 16700: (174, 201, 255), 16800: (174, 201, 255), 16900: (174, 200, 255), 17000: (174, 200, 255), 17100: (173, 200, 255), 17200: (173, 200, 255), 17300: (173, 200, 255), 17400: (173, 200, 255), 17500: (173, 200, 255), 17600: (172, 199, 255), 17700: (172, 199, 255), 17800: (172, 199, 255), 17900: (172, 199, 255), 18000: (172, 199, 255), 18100: (171, 199, 255), 18200: (171, 199, 255), 18300: (171, 199, 255), 18400: (171, 198, 255), 18500: (171, 198, 255), 18600: (170, 198, 255), 18700: (170, 198, 255), 18800: (170, 198, 255), 18900: (170, 198, 255), 19000: (170, 198, 255), 19100: (170, 198, 255), 19200: (169, 198, 255), 19300: (169, 197, 255), 19400: (169, 197, 255), 19500: (169, 197, 255), 19600: (169, 197, 255), 19700: (169, 197, 255), 19800: (169, 197, 255), 19900: (168, 197, 255), 20000: (168, 197, 255), 20100: (168, 197, 255), 20200: (168, 197, 255), 20300: (168, 196, 255), 20400: (168, 196, 255), 20500: (168, 196, 255), 20600: (167, 196, 255), 20700: (167, 196, 255), 20800: (167, 196, 255), 20900: (167, 196, 255), 21000: (167, 196, 255), 21100: (167, 196, 255), 21200: (167, 196, 255), 21300: (166, 196, 255), 21400: (166, 195, 255), 21500: (166, 195, 255), 21600: (166, 195, 255), 21700: (166, 195, 255), 21800: (166, 195, 255), 21900: (166, 195, 255), 22000: (166, 195, 255), 22100: (165, 195, 255), 22200: (165, 195, 255), 22300: (165, 195, 255), 22400: (165, 195, 255), 22500: (165, 195, 255), 22600: (165, 195, 255), 22700: (165, 194, 255), 22800: (165, 194, 255), 22900: (165, 194, 255), 23000: (164, 194, 255), 23100: (164, 194, 255), 23200: (164, 194, 255), 23300: (164, 194, 255), 23400: (164, 194, 255), 23500: (164, 194, 255), 23600: (164, 194, 255), 23700: (164, 194, 255), 23800: (164, 194, 255), 23900: (164, 194, 255), 24000: (163, 194, 255), 24100: (163, 194, 255), 24200: (163, 193, 255), 24300: (163, 193, 255), 24400: (163, 193, 255), 24500: (163, 193, 255), 24600: (163, 193, 255), 24700: (163, 193, 255), 24800: (163, 193, 255), 24900: (163, 193, 255), 25000: (163, 193, 255), 25100: (162, 193, 255), 25200: (162, 193, 255), 25300: (162, 193, 255), 25400: (162, 193, 255), 25500: (162, 193, 255), 25600: (162, 193, 255), 25700: (162, 193, 255), 25800: (162, 193, 255), 25900: (162, 192, 255), 26000: (162, 192, 255), 26100: (162, 192, 255), 26200: (162, 192, 255), 26300: (162, 192, 255), 26400: (161, 192, 255), 26500: (161, 192, 255), 26600: (161, 192, 255), 26700: (161, 192, 255), 26800: (161, 192, 255), 26900: (161, 192, 255), 27000: (161, 192, 255), 27100: (161, 192, 255), 27200: (161, 192, 255), 27300: (161, 192, 255), 27400: (161, 192, 255), 27500: (161, 192, 255), 27600: (161, 192, 255), 27700: (161, 192, 255), 27800: (160, 192, 255), 27900: (160, 192, 255), 28000: (160, 191, 255), 28100: (160, 191, 255), 28200: (160, 191, 255), 28300: (160, 191, 255), 28400: (160, 191, 255), 28500: (160, 191, 255), 28600: (160, 191, 255), 28700: (160, 191, 255), 28800: (160, 191, 255), 28900: (160, 191, 255), 29000: (160, 191, 255), 29100: (160, 191, 255), 29200: (160, 191, 255), 29300: (159, 191, 255), 29400: (159, 191, 255), 29500: (159, 191, 255), 29600: (159, 191, 255), 29700: (159, 191, 255), 29800: (159, 191, 255), 29900: (159, 191, 255), 30000: (159, 191, 255), 30100: (159, 191, 255), 30200: (159, 191, 255), 30300: (159, 191, 255), 30400: (159, 190, 255), 30500: (159, 190, 255), 30600: (159, 190, 255), 30700: (159, 190, 255), 30800: (159, 190, 255), 30900: (159, 190, 255), 31000: (159, 190, 255), 31100: (158, 190, 255), 31200: (158, 190, 255), 31300: (158, 190, 255), 31400: (158, 190, 255), 31500: (158, 190, 255), 31600: (158, 190, 255), 31700: (158, 190, 255), 31800: (158, 190, 255), 31900: (158, 190, 255), 32000: (158, 190, 255), 32100: (158, 190, 255), 32200: (158, 190, 255), 32300: (158, 190, 255), 32400: (158, 190, 255), 32500: (158, 190, 255), 32600: (158, 190, 255), 32700: (158, 190, 255), 32800: (158, 190, 255), 32900: (158, 190, 255), 33000: (158, 190, 255), 33100: (158, 190, 255), 33200: (157, 190, 255), 33300: (157, 190, 255), 33400: (157, 189, 255), 33500: (157, 189, 255), 33600: (157, 189, 255), 33700: (157, 189, 255), 33800: (157, 189, 255), 33900: (157, 189, 255), 34000: (157, 189, 255), 34100: (157, 189, 255), 34200: (157, 189, 255), 34300: (157, 189, 255), 34400: (157, 189, 255), 34500: (157, 189, 255), 34600: (157, 189, 255), 34700: (157, 189, 255), 34800: (157, 189, 255), 34900: (157, 189, 255), 35000: (157, 189, 255), 35100: (157, 189, 255), 35200: (157, 189, 255), 35300: (157, 189, 255), 35400: (157, 189, 255), 35500: (157, 189, 255), 35600: (156, 189, 255), 35700: (156, 189, 255), 35800: (156, 189, 255), 35900: (156, 189, 255), 36000: (156, 189, 255), 36100: (156, 189, 255), 36200: (156, 189, 255), 36300: (156, 189, 255), 36400: (156, 189, 255), 36500: (156, 189, 255), 36600: (156, 189, 255), 36700: (156, 189, 255), 36800: (156, 189, 255), 36900: (156, 189, 255), 37000: (156, 189, 255), 37100: (156, 189, 255), 37200: (156, 188, 255), 37300: (156, 188, 255), 37400: (156, 188, 255), 37500: (156, 188, 255), 37600: (156, 188, 255), 37700: (156, 188, 255), 37800: (156, 188, 255), 37900: (156, 188, 255), 38000: (156, 188, 255), 38100: (156, 188, 255), 38200: (156, 188, 255), 38300: (156, 188, 255), 38400: (155, 188, 255), 38500: (155, 188, 255), 38600: (155, 188, 255), 38700: (155, 188, 255), 38800: (155, 188, 255), 38900: (155, 188, 255), 39000: (155, 188, 255), 39100: (155, 188, 255), 39200: (155, 188, 255), 39300: (155, 188, 255), 39400: (155, 188, 255), 39500: (155, 188, 255), 39600: (155, 188, 255), 39700: (155, 188, 255), 39800: (155, 188, 255), 39900: (155, 188, 255), 40000: (155, 188, 255) } def start(self): self.cbe_color.set_period(50) self.cbe_illuminance.set_period(100) self.cbe_color_temperature.set_period(100) async_call(self.color.get_config, None, self.get_config_async, self.increase_error_count) async_call(self.color.is_light_on, None, self.is_light_on_async, self.increase_error_count) self.plot_widget.stop = False self.plot_widget_illuminance.stop = False self.plot_widget_color_temperature.stop = False def stop(self): self.cbe_color.set_period(0) self.cbe_illuminance.set_period(0) self.cbe_color_temperature.set_period(0) self.plot_widget.stop = True self.plot_widget_illuminance.stop = True self.plot_widget_color_temperature.stop = True def destroy(self): pass @staticmethod def has_device_identifier(device_identifier): return device_identifier == BrickletColor.DEVICE_IDENTIFIER def format_color(self, i, value): if value >= 65535: self.plot_widget.get_key_item(i).setStyleSheet( 'QToolButton { color: red }') else: self.plot_widget.get_key_item(i).setStyleSheet('') return str(value) def cb_color(self, r, g, b, c): self.current_color_r.value = r self.current_color_g.value = g self.current_color_b.value = b self.current_color_c.value = c if r >= 65535 or g >= 65535 or b >= 65535: self.plot_widget_illuminance.get_key_item(0).setStyleSheet( 'QLabel { color: red }') self.plot_widget_color_temperature.get_key_item(0).setStyleSheet( 'QLabel { color: red }') else: self.plot_widget_illuminance.get_key_item(0).setStyleSheet('') self.plot_widget_color_temperature.get_key_item(0).setStyleSheet( '') normalize = 0xFFFF self.color_frame.set_color( QColor(r * 255 // normalize, g * 255 // normalize, b * 255 // normalize)) def cb_illuminance(self, illuminance): self.current_illuminance.value = round( illuminance * 700.0 / self.current_gain_factor / self.current_conversion_time, 1) i = int(self.current_illuminance.value) * 255 // 20000 if i > 255: i = 255 self.illuminance_frame.set_color(QColor(i, i, i)) def cb_color_temperature(self, color_temperature): self.current_color_temperature.value = color_temperature m = color_temperature % 100 color_temperature -= m if m > 50: color_temperature += 100 if color_temperature < 1000: color_temperature = 1000 if color_temperature > 40000: color_temperature = 40000 r, g, b = self.k_to_rgb[color_temperature] self.color_temperature_frame.set_color(QColor(r, g, b)) def is_light_on_async(self, light): self.light_checkbox.setChecked(light == BrickletColor.LIGHT_ON) def light_state_changed(self, state): if state == Qt.Checked: self.color.light_on() else: self.color.light_off() def get_config_async(self, config): gain, gain_factor, conv, conv_time = self.gain_conv_to_combo( config.gain, config.integration_time) self.gain_combo.setCurrentIndex(gain) self.conversion_combo.setCurrentIndex(conv) self.current_gain_factor = gain_factor self.current_conversion_time = conv_time def gain_conv_to_combo(self, gain, conv): if gain == BrickletColor.GAIN_1X: gain = 0 gain_factor = 1 elif gain == BrickletColor.GAIN_4X: gain = 1 gain_factor = 4 elif gain == BrickletColor.GAIN_16X: gain = 2 gain_factor = 16 elif gain == BrickletColor.GAIN_60X: gain = 3 gain_factor = 60 if conv == BrickletColor.INTEGRATION_TIME_2MS: conv = 0 conv_time = 2.4 elif conv == BrickletColor.INTEGRATION_TIME_24MS: conv = 1 conv_time = 24 elif conv == BrickletColor.INTEGRATION_TIME_101MS: conv = 2 conv_time = 101 elif conv == BrickletColor.INTEGRATION_TIME_154MS: conv = 3 conv_time = 154 elif conv == BrickletColor.INTEGRATION_TIME_700MS: conv = 4 conv_time = 700 return gain, gain_factor, conv, conv_time def combo_to_gain_conv(self, gain, conv): if gain == 0: gain = BrickletColor.GAIN_1X gain_factor = 1 elif gain == 1: gain = BrickletColor.GAIN_4X gain_factor = 4 elif gain == 2: gain = BrickletColor.GAIN_16X gain_factor = 16 elif gain == 3: gain = BrickletColor.GAIN_60X gain_factor = 60 if conv == 0: conv = BrickletColor.INTEGRATION_TIME_2MS conv_time = 2.4 elif conv == 1: conv = BrickletColor.INTEGRATION_TIME_24MS conv_time = 24 elif conv == 2: conv = BrickletColor.INTEGRATION_TIME_101MS conv_time = 101 elif conv == 3: conv = BrickletColor.INTEGRATION_TIME_154MS conv_time = 154 elif conv == 4: conv = BrickletColor.INTEGRATION_TIME_700MS conv_time = 700 return gain, gain_factor, conv, conv_time def gain_changed(self, gain): conversion = self.conversion_combo.currentIndex() g, gf, c, ct = self.combo_to_gain_conv(gain, conversion) self.current_gain_factor = gf self.current_conversion_time = ct self.color.set_config(g, c) def conversion_changed(self, conversion): gain = self.gain_combo.currentIndex() g, gf, c, ct = self.combo_to_gain_conv(gain, conversion) self.current_gain_factor = gf self.current_conversion_time = ct self.color.set_config(g, c)
class IMU(PluginBase, Ui_IMU): def __init__(self, *args): PluginBase.__init__(self, BrickIMU, *args) self.setupUi(self) self.imu = self.device self.acc_x = 0 self.acc_y = 0 self.acc_z = 0 self.mag_x = 0 self.mag_y = 0 self.mag_z = 0 self.gyr_x = 0 self.gyr_y = 0 self.gyr_z = 0 self.tem = 0 self.roll = 0 self.pitch = 0 self.yaw = 0 self.qua_x = 0 self.qua_y = 0 self.qua_z = 0 self.qua_w = 0 self.old_time = 0 self.update_timer = QTimer() self.update_timer.timeout.connect(self.update_data) self.cbe_all_data = CallbackEmulator(self.imu.get_all_data, self.all_data_callback, self.increase_error_count, use_data_signal=False) self.cbe_orientation = CallbackEmulator(self.imu.get_orientation, self.orientation_callback, self.increase_error_count, use_data_signal=False) self.cbe_quaternion = CallbackEmulator(self.imu.get_quaternion, self.quaternion_callback, self.increase_error_count, use_data_signal=False) # Import IMUGLWidget here, not global. If globally included we get # 'No OpenGL_accelerate module loaded: No module named OpenGL_accelerate' # as soon as IMU is set as device_class in __init__. # No idea why this happens, doesn't make sense. try: from .imu_gl_widget import IMUGLWidget except: from imu_gl_widget import IMUGLWidget self.imu_gl = IMUGLWidget(self) self.imu_gl.setMinimumSize(150, 150) self.imu_gl.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.min_x = 0 self.min_y = 0 self.min_z = 0 self.max_x = 0 self.max_y = 0 self.max_z = 0 self.update_counter = 0 self.mag_plot_widget = PlotWidget("Magnetic Field [mG]", [["X", Qt.red, self.get_mag_x], ["Y", Qt.darkGreen, self.get_mag_y], ["Z", Qt.blue, self.get_mag_z]], self.clear_graphs) self.acc_plot_widget = PlotWidget("Acceleration [mG]", [["X", Qt.red, self.get_acc_x], ["Y", Qt.darkGreen, self.get_acc_y], ["Z", Qt.blue, self.get_acc_z]], self.clear_graphs) self.gyr_plot_widget = PlotWidget("Angular Velocity [%c/s]" % 0xB0, [["X", Qt.red, self.get_gyr_x], ["Y", Qt.darkGreen, self.get_gyr_y], ["Z", Qt.blue, self.get_gyr_z]], self.clear_graphs) self.tem_plot_widget = PlotWidget("Temperature [%cC]" % 0xB0, [["t", Qt.red, self.get_tem]], self.clear_graphs) self.mag_plot_widget.setMinimumSize(250, 200) self.acc_plot_widget.setMinimumSize(250, 200) self.gyr_plot_widget.setMinimumSize(250, 200) self.tem_plot_widget.setMinimumSize(250, 200) self.orientation_label = QLabel("""Position your IMU Brick as shown \ in the image above, then press "Save Orientation".""") self.orientation_label.setWordWrap(True) self.orientation_label.setAlignment(Qt.AlignHCenter) self.gl_layout = QVBoxLayout() self.gl_layout.addWidget(self.imu_gl) self.gl_layout.addWidget(self.orientation_label) self.layout_top.addWidget(self.gyr_plot_widget) self.layout_top.addWidget(self.acc_plot_widget) self.layout_top.addWidget(self.mag_plot_widget) self.layout_bottom.addLayout(self.gl_layout) self.layout_bottom.addWidget(self.tem_plot_widget) self.save_orientation.clicked.connect(self.imu_gl.save_orientation) self.calibrate.clicked.connect(self.calibrate_clicked) self.led_button.clicked.connect(self.led_clicked) self.speed_spinbox.editingFinished.connect(self.speed_finished) self.calibrate = None self.alive = True if self.firmware_version >= (1, 0, 7): reset = QAction('Reset', self) reset.triggered.connect(lambda: self.imu.reset()) self.set_actions(reset) def start(self): if not self.alive: return self.gl_layout.activate() self.cbe_all_data.set_period(100) self.cbe_orientation.set_period(100) self.cbe_quaternion.set_period(50) self.update_timer.start(50) async_call(self.imu.get_convergence_speed, None, self.speed_spinbox.setValue, self.increase_error_count) self.mag_plot_widget.stop = False self.acc_plot_widget.stop = False self.gyr_plot_widget.stop = False self.tem_plot_widget.stop = False def stop(self): self.mag_plot_widget.stop = True self.acc_plot_widget.stop = True self.gyr_plot_widget.stop = True self.tem_plot_widget.stop = True self.update_timer.stop() self.cbe_all_data.set_period(0) self.cbe_orientation.set_period(0) self.cbe_quaternion.set_period(0) def destroy(self): self.alive = False if self.calibrate: self.calibrate.close() def get_url_part(self): return 'imu' @staticmethod def has_device_identifier(device_identifier): return device_identifier == BrickIMU.DEVICE_IDENTIFIER def all_data_callback(self, data): acc_x, acc_y, acc_z, mag_x, mag_y, mag_z, gyr_x, gyr_y, gyr_z, tem = data self.acc_x = acc_x self.acc_y = acc_y self.acc_z = acc_z self.mag_x = mag_x self.mag_y = mag_y self.mag_z = mag_z self.gyr_x = gyr_x self.gyr_y = gyr_y self.gyr_z = gyr_z self.tem = tem def quaternion_callback(self, data): qua_x, qua_y, qua_z, qua_w = data self.qua_x = qua_x self.qua_y = qua_y self.qua_z = qua_z self.qua_w = qua_w def orientation_callback(self, data): roll, pitch, yaw = data self.roll = roll self.pitch = pitch self.yaw = yaw def led_clicked(self): if 'On' in self.led_button.text(): self.led_button.setText('Turn LEDs Off') self.imu.leds_on() elif 'Off' in self.led_button.text(): self.led_button.setText('Turn LEDs On') self.imu.leds_off() def get_acc_x(self): return self.acc_x def get_acc_y(self): return self.acc_y def get_acc_z(self): return self.acc_z def get_mag_x(self): return self.mag_x def get_mag_y(self): return self.mag_y def get_mag_z(self): return self.mag_z def get_gyr_x(self): return self.gyr_x/14.375 def get_gyr_y(self): return self.gyr_y/14.375 def get_gyr_z(self): return self.gyr_z/14.375 def get_tem(self): return self.tem/100.0 def update_data(self): self.update_counter += 1 self.imu_gl.update(self.qua_x, self.qua_y, self.qua_z, self.qua_w) if self.update_counter % 2: gyr_x = self.gyr_x/14.375 gyr_y = self.gyr_y/14.375 gyr_z = self.gyr_z/14.375 self.acceleration_update(self.acc_x, self.acc_y, self.acc_z) self.magnetometer_update(self.mag_x, self.mag_y, self.mag_z) self.gyroscope_update(gyr_x, gyr_y, gyr_z) self.orientation_update(self.roll, self.pitch, self.yaw) self.temperature_update(self.tem) def acceleration_update(self, x, y, z): x_str = "%g" % x y_str = "%g" % y z_str = "%g" % z self.acc_y_label.setText(y_str) self.acc_x_label.setText(x_str) self.acc_z_label.setText(z_str) def magnetometer_update(self, x, y, z): # Earth magnetic field. 0.5 Gauss x_str = "%g" % x y_str = "%g" % y z_str = "%g" % z self.mag_x_label.setText(x_str) self.mag_y_label.setText(y_str) self.mag_z_label.setText(z_str) def gyroscope_update(self, x, y, z): x_str = "%g" % int(x) y_str = "%g" % int(y) z_str = "%g" % int(z) self.gyr_x_label.setText(x_str) self.gyr_y_label.setText(y_str) self.gyr_z_label.setText(z_str) def orientation_update(self, r, p, y): r_str = "%g" % (r/100) p_str = "%g" % (p/100) y_str = "%g" % (y/100) self.roll_label.setText(r_str) self.pitch_label.setText(p_str) self.yaw_label.setText(y_str) def temperature_update(self, t): t_str = "%.2f" % (t/100.0) self.tem_label.setText(t_str) def calibrate_clicked(self): self.stop() if self.calibrate is None: self.calibrate = CalibrateWindow(self) self.calibrate.refresh_values() self.calibrate.show() def speed_finished(self): speed = self.speed_spinbox.value() self.imu.set_convergence_speed(speed)
class IMU(PluginBase, Ui_IMU): def __init__(self, *args): PluginBase.__init__(self, BrickIMU, *args) self.setupUi(self) self.imu = self.device # the firmware version of a Brick can (under common circumstances) not # change during the lifetime of a Brick plugin. therefore, it's okay to # make final decisions based on it here self.has_status_led = self.firmware_version >= (2, 3, 1) self.acc_x = CurveValueWrapper() self.acc_y = CurveValueWrapper() self.acc_z = CurveValueWrapper() self.mag_x = CurveValueWrapper() self.mag_y = CurveValueWrapper() self.mag_z = CurveValueWrapper() self.gyr_x = CurveValueWrapper() self.gyr_y = CurveValueWrapper() self.gyr_z = CurveValueWrapper() self.temp = CurveValueWrapper() self.roll = None self.pitch = None self.yaw = None self.qua_x = None self.qua_y = None self.qua_z = None self.qua_w = None self.all_data_valid = False self.quaternion_valid = False self.orientation_valid = False self.update_timer = QTimer(self) self.update_timer.timeout.connect(self.update_data) self.cbe_all_data = CallbackEmulator(self.imu.get_all_data, None, self.cb_all_data, self.increase_error_count, expand_result_tuple_for_callback=True, use_result_signal=False) self.cbe_orientation = CallbackEmulator(self.imu.get_orientation, None, self.cb_orientation, self.increase_error_count, expand_result_tuple_for_callback=True, use_result_signal=False) self.cbe_quaternion = CallbackEmulator(self.imu.get_quaternion, None, self.cb_quaternion, self.increase_error_count, expand_result_tuple_for_callback=True, use_result_signal=False) self.imu_gl = IMU3DWidget(self) self.imu_gl.setMinimumSize(150, 150) self.imu_gl.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.update_counter = 0 self.mag_plot_widget = PlotWidget("Magnetic Field [mG]", [("X", Qt.red, self.mag_x, str), ("Y", Qt.darkGreen, self.mag_y, str), ("Z", Qt.blue, self.mag_z, str)], clear_button=self.clear_graphs, key='right-no-icon', y_resolution=5) self.acc_plot_widget = PlotWidget("Acceleration [mg]", [("X", Qt.red, self.acc_x, str), ("Y", Qt.darkGreen, self.acc_y, str), ("Z", Qt.blue, self.acc_z, str)], clear_button=self.clear_graphs, key='right-no-icon', y_resolution=5) self.gyr_plot_widget = PlotWidget("Angular Velocity [°/s]", [("X", Qt.red, self.gyr_x, str), ("Y", Qt.darkGreen, self.gyr_y, str), ("Z", Qt.blue, self.gyr_z, str)], clear_button=self.clear_graphs, key='right-no-icon', y_resolution=0.05) self.temp_plot_widget = PlotWidget("Temperature [°C]", [("t", Qt.red, self.temp, str)], clear_button=self.clear_graphs, key=None, y_resolution=0.01) self.mag_plot_widget.setMinimumSize(250, 250) self.acc_plot_widget.setMinimumSize(250, 250) self.gyr_plot_widget.setMinimumSize(250, 250) self.temp_plot_widget.setMinimumSize(250, 250) self.orientation_label = QLabel('Position your IMU Brick as shown in the image above, then press "Save Orientation".') self.orientation_label.setWordWrap(True) self.orientation_label.setAlignment(Qt.AlignHCenter) self.gl_layout = QVBoxLayout() self.gl_layout.addWidget(self.imu_gl) self.gl_layout.addWidget(self.orientation_label) self.layout_top.addWidget(self.gyr_plot_widget) self.layout_top.addWidget(self.acc_plot_widget) self.layout_top.addWidget(self.mag_plot_widget) self.layout_bottom.addLayout(self.gl_layout) self.layout_bottom.addWidget(self.temp_plot_widget) self.save_orientation.clicked.connect(self.save_orientation_clicked) self.calibrate.clicked.connect(self.calibrate_clicked) self.led_button.clicked.connect(self.led_clicked) self.speed_spinbox.editingFinished.connect(self.speed_finished) width = QFontMetrics(self.gyr_x_label.font()).boundingRect('-XXXX.X').width() self.gyr_x_label.setMinimumWidth(width) self.gyr_y_label.setMinimumWidth(width) self.gyr_z_label.setMinimumWidth(width) self.calibrate = None self.alive = True if self.has_status_led: self.status_led_action = QAction('Status LED', self) self.status_led_action.setCheckable(True) self.status_led_action.toggled.connect(lambda checked: self.imu.enable_status_led() if checked else self.imu.disable_status_led()) self.set_configs([(0, None, [self.status_led_action])]) else: self.status_led_action = None reset = QAction('Reset', self) reset.triggered.connect(self.imu.reset) self.set_actions([(0, None, [reset])]) def save_orientation_clicked(self): self.imu_gl.save_orientation() self.orientation_label.hide() def cleanup_gl(self): self.state = self.imu_gl.get_state() self.imu_gl.hide() self.imu_gl.cleanup() def restart_gl(self): self.imu_gl = IMU3DWidget() self.imu_gl.setMinimumSize(150, 150) self.imu_gl.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.gl_layout.addWidget(self.imu_gl) self.imu_gl.show() self.save_orientation.clicked.connect(self.save_orientation_clicked) self.imu_gl.set_state(self.state) def start(self): if not self.alive: return if self.has_status_led: async_call(self.imu.is_status_led_enabled, None, self.status_led_action.setChecked, self.increase_error_count) self.parent().add_callback_on_untab(lambda x: self.cleanup_gl(), 'imu_cleanup_on_untab') self.parent().add_callback_post_untab(lambda x: self.restart_gl(), 'imu_restart_post_untab') self.parent().add_callback_on_tab(lambda x: self.cleanup_gl(), 'imu_cleanup_on_tab') self.parent().add_callback_post_tab(lambda x: self.restart_gl(), 'imu_restart_post_tab') self.gl_layout.activate() self.cbe_all_data.set_period(100) self.cbe_orientation.set_period(100) self.cbe_quaternion.set_period(50) self.update_timer.start(50) async_call(self.imu.get_convergence_speed, None, self.speed_spinbox.setValue, self.increase_error_count) self.mag_plot_widget.stop = False self.acc_plot_widget.stop = False self.gyr_plot_widget.stop = False self.temp_plot_widget.stop = False def stop(self): self.mag_plot_widget.stop = True self.acc_plot_widget.stop = True self.gyr_plot_widget.stop = True self.temp_plot_widget.stop = True self.update_timer.stop() self.cbe_all_data.set_period(0) self.cbe_orientation.set_period(0) self.cbe_quaternion.set_period(0) def destroy(self): self.alive = False self.cleanup_gl() if self.calibrate: self.calibrate.close() @staticmethod def has_device_identifier(device_identifier): return device_identifier == BrickIMU.DEVICE_IDENTIFIER def cb_all_data(self, acc_x, acc_y, acc_z, mag_x, mag_y, mag_z, gyr_x, gyr_y, gyr_z, temp): self.acc_x.value = acc_x self.acc_y.value = acc_y self.acc_z.value = acc_z self.mag_x.value = mag_x self.mag_y.value = mag_y self.mag_z.value = mag_z self.gyr_x.value = gyr_x / 14.375 self.gyr_y.value = gyr_y / 14.375 self.gyr_z.value = gyr_z / 14.375 self.temp.value = temp / 100.0 self.all_data_valid = True def cb_quaternion(self, x, y, z, w): self.qua_x = x self.qua_y = y self.qua_z = z self.qua_w = w self.quaternion_valid = True def cb_orientation(self, roll, pitch, yaw): self.roll = roll / 100.0 self.pitch = pitch / 100.0 self.yaw = yaw / 100.0 self.orientation_valid = True def led_clicked(self): if 'On' in self.led_button.text().replace('&', ''): self.led_button.setText('Turn LEDs Off') self.imu.leds_on() elif 'Off' in self.led_button.text().replace('&', ''): self.led_button.setText('Turn LEDs On') self.imu.leds_off() def update_data(self): self.update_counter += 1 if self.quaternion_valid: self.imu_gl.update_orientation(self.qua_w, self.qua_x, self.qua_y, self.qua_z) if self.update_counter == 2: self.update_counter = 0 if self.all_data_valid and self.orientation_valid: self.acceleration_update(self.acc_x.value, self.acc_y.value, self.acc_z.value) self.magnetometer_update(self.mag_x.value, self.mag_y.value, self.mag_z.value) self.gyroscope_update(self.gyr_x.value, self.gyr_y.value, self.gyr_z.value) self.orientation_update(self.roll, self.pitch, self.yaw) self.temperature_update(self.temp.value) def acceleration_update(self, x, y, z): self.acc_y_label.setText(format(x, '.1f')) self.acc_x_label.setText(format(y, '.1f')) self.acc_z_label.setText(format(z, '.1f')) def magnetometer_update(self, x, y, z): # Earth magnetic field: 0.5 Gauss self.mag_x_label.setText(format(x, '.1f')) self.mag_y_label.setText(format(y, '.1f')) self.mag_z_label.setText(format(z, '.1f')) def gyroscope_update(self, x, y, z): self.gyr_x_label.setText(format(x, '.1f')) self.gyr_y_label.setText(format(y, '.1f')) self.gyr_z_label.setText(format(z, '.1f')) def orientation_update(self, r, p, y): self.roll_label.setText(format(r, '.1f')) self.pitch_label.setText(format(p, '.1f')) self.yaw_label.setText(format(y, '.1f')) def temperature_update(self, t): self.tem_label.setText(format(t, '.1f')) def calibrate_clicked(self): self.stop() if self.calibrate is None: self.calibrate = CalibrateWindow(self) self.calibrate.refresh_values() self.calibrate.show() def speed_finished(self): speed = self.speed_spinbox.value() self.imu.set_convergence_speed(speed)
class Color(PluginBase): def __init__(self, *args): PluginBase.__init__(self, BrickletColor, *args) self.color = self.device self.cbe_color = CallbackEmulator(self.color.get_color, self.cb_color_get, self.increase_error_count) self.cbe_illuminance = CallbackEmulator(self.color.get_illuminance, self.cb_illuminance_get, self.increase_error_count) self.cbe_color_temperature = CallbackEmulator( self.color.get_color_temperature, self.cb_color_temperature_get, self.increase_error_count) self.color_label = ColorLabel() self.illuminance_label = IlluminanceLabel() self.color_temperature_label = ColorTemperatureLabel() self.color_frame = ColorFrame() self.color_temperature_frame = ColorFrame() self.illuminance_frame = ColorFrame() self.current_color = (0, 0, 0, 0) self.current_illuminance = 0 self.current_color_temperature = 0 self.clear_graphs_button = QPushButton("Clear Graphs") plot_list = [['R', Qt.red, self.get_current_r], ['G', Qt.darkGreen, self.get_current_g], ['B', Qt.blue, self.get_current_b], ['C', Qt.black, self.get_current_c]] self.plot_widget = PlotWidget('Color Value', plot_list, self.clear_graphs_button) self.plot_widget.setMinimumSize(250, 200) plot_list_illuminance = [[ '', Qt.red, self.get_current_illuminance_value ]] self.plot_widget_illuminance = PlotWidget('Illuminance [Lux]', plot_list_illuminance, self.clear_graphs_button) self.plot_widget_illuminance.setMinimumSize(250, 200) plot_list_color_temperature = [[ '', Qt.red, self.get_current_color_temperature_value ]] self.plot_widget_color_temperature = PlotWidget( 'Color Temperature [K]', plot_list_color_temperature, self.clear_graphs_button) self.plot_widget_color_temperature.setMinimumSize(250, 200) self.gain_label = QLabel('Gain: ') self.gain_combo = QComboBox() self.gain_combo.addItem("1x") self.gain_combo.addItem("4x") self.gain_combo.addItem("16x") self.gain_combo.addItem("60x") self.gain_combo.currentIndexChanged.connect(self.gain_changed) self.current_gain_factor = 60 self.conversion_label = QLabel('Integration Time: ') self.conversion_combo = QComboBox() self.conversion_combo.addItem("2.4ms") self.conversion_combo.addItem("24ms") self.conversion_combo.addItem("101ms") self.conversion_combo.addItem("154ms") self.conversion_combo.addItem("700ms") self.current_conversion_time = 154 self.conversion_combo.currentIndexChanged.connect( self.conversion_changed) self.light_checkbox = QCheckBox("Enable Light") self.light_checkbox.stateChanged.connect(self.light_state_changed) layout_config = QHBoxLayout() layout_config.addWidget(self.gain_label) layout_config.addWidget(self.gain_combo) layout_config.addWidget(self.conversion_label) layout_config.addWidget(self.conversion_combo) layout_config.addWidget(self.clear_graphs_button, 1) layout_config.addWidget(self.light_checkbox) layout_ht1 = QHBoxLayout() layout_ht1.addStretch() layout_ht1.addWidget(self.illuminance_label) layout_ht1.addWidget(self.illuminance_frame) layout_ht1.addStretch() layout_ht2 = QHBoxLayout() layout_ht2.addStretch() layout_ht2.addWidget(self.color_temperature_label) layout_ht2.addWidget(self.color_temperature_frame) layout_ht2.addStretch() layout_v1 = QVBoxLayout() layout_v1.addLayout(layout_ht1) layout_v1.addWidget(self.plot_widget_illuminance) layout_v2 = QVBoxLayout() layout_v2.addLayout(layout_ht2) layout_v2.addWidget(self.plot_widget_color_temperature) layout_h2 = QHBoxLayout() layout_h2.addLayout(layout_v1) layout_h2.addLayout(layout_v2) layout_h = QHBoxLayout() layout_h.addStretch() layout_h.addWidget(self.color_label) layout_h.addWidget(self.color_frame) layout_h.addStretch() layout = QVBoxLayout(self) layout.addLayout(layout_h) layout.addWidget(self.plot_widget) layout.addLayout(layout_h2) layout.addLayout(layout_config) self.k_to_rgb = { 1000: (255, 56, 0), 1100: (255, 71, 0), 1200: (255, 83, 0), 1300: (255, 93, 0), 1400: (255, 101, 0), 1500: (255, 109, 0), 1600: (255, 115, 0), 1700: (255, 121, 0), 1800: (255, 126, 0), 1900: (255, 131, 0), 2000: (255, 137, 18), 2100: (255, 142, 33), 2200: (255, 147, 44), 2300: (255, 152, 54), 2400: (255, 157, 63), 2500: (255, 161, 72), 2600: (255, 165, 79), 2700: (255, 169, 87), 2800: (255, 173, 94), 2900: (255, 177, 101), 3000: (255, 180, 107), 3100: (255, 184, 114), 3200: (255, 187, 120), 3300: (255, 190, 126), 3400: (255, 193, 132), 3500: (255, 196, 137), 3600: (255, 199, 143), 3700: (255, 201, 148), 3800: (255, 204, 153), 3900: (255, 206, 159), 4000: (255, 209, 163), 4100: (255, 211, 168), 4200: (255, 213, 173), 4300: (255, 215, 177), 4400: (255, 217, 182), 4500: (255, 219, 186), 4600: (255, 221, 190), 4700: (255, 223, 194), 4800: (255, 225, 198), 4900: (255, 227, 202), 5000: (255, 228, 206), 5100: (255, 230, 210), 5200: (255, 232, 213), 5300: (255, 233, 217), 5400: (255, 235, 220), 5500: (255, 236, 224), 5600: (255, 238, 227), 5700: (255, 239, 230), 5800: (255, 240, 233), 5900: (255, 242, 236), 6000: (255, 243, 239), 6100: (255, 244, 242), 6200: (255, 245, 245), 6300: (255, 246, 248), 6400: (255, 248, 251), 6500: (255, 249, 253), 6600: (254, 249, 255), 6700: (252, 247, 255), 6800: (249, 246, 255), 6900: (247, 245, 255), 7000: (245, 243, 255), 7100: (243, 242, 255), 7200: (240, 241, 255), 7300: (239, 240, 255), 7400: (237, 239, 255), 7500: (235, 238, 255), 7600: (233, 237, 255), 7700: (231, 236, 255), 7800: (230, 235, 255), 7900: (228, 234, 255), 8000: (227, 233, 255), 8100: (225, 232, 255), 8200: (224, 231, 255), 8300: (222, 230, 255), 8400: (221, 230, 255), 8500: (220, 229, 255), 8600: (218, 228, 255), 8700: (217, 227, 255), 8800: (216, 227, 255), 8900: (215, 226, 255), 9000: (214, 225, 255), 9100: (212, 225, 255), 9200: (211, 224, 255), 9300: (210, 223, 255), 9400: (209, 223, 255), 9500: (208, 222, 255), 9600: (207, 221, 255), 9700: (207, 221, 255), 9800: (206, 220, 255), 9900: (205, 220, 255), 10000: (204, 219, 255), 10100: (203, 219, 255), 10200: (202, 218, 255), 10300: (201, 218, 255), 10400: (201, 217, 255), 10500: (200, 217, 255), 10600: (199, 216, 255), 10700: (199, 216, 255), 10800: (198, 216, 255), 10900: (197, 215, 255), 11000: (196, 215, 255), 11100: (196, 214, 255), 11200: (195, 214, 255), 11300: (195, 214, 255), 11400: (194, 213, 255), 11500: (193, 213, 255), 11600: (193, 212, 255), 11700: (192, 212, 255), 11800: (192, 212, 255), 11900: (191, 211, 255), 12000: (191, 211, 255), 12100: (190, 211, 255), 12200: (190, 210, 255), 12300: (189, 210, 255), 12400: (189, 210, 255), 12500: (188, 210, 255), 12600: (188, 209, 255), 12700: (187, 209, 255), 12800: (187, 209, 255), 12900: (186, 208, 255), 13000: (186, 208, 255), 13100: (185, 208, 255), 13200: (185, 208, 255), 13300: (185, 207, 255), 13400: (184, 207, 255), 13500: (184, 207, 255), 13600: (183, 207, 255), 13700: (183, 206, 255), 13800: (183, 206, 255), 13900: (182, 206, 255), 14000: (182, 206, 255), 14100: (182, 205, 255), 14200: (181, 205, 255), 14300: (181, 205, 255), 14400: (181, 205, 255), 14500: (180, 205, 255), 14600: (180, 204, 255), 14700: (180, 204, 255), 14800: (179, 204, 255), 14900: (179, 204, 255), 15000: (179, 204, 255), 15100: (178, 203, 255), 15200: (178, 203, 255), 15300: (178, 203, 255), 15400: (178, 203, 255), 15500: (177, 203, 255), 15600: (177, 202, 255), 15700: (177, 202, 255), 15800: (177, 202, 255), 15900: (176, 202, 255), 16000: (176, 202, 255), 16100: (176, 202, 255), 16200: (175, 201, 255), 16300: (175, 201, 255), 16400: (175, 201, 255), 16500: (175, 201, 255), 16600: (175, 201, 255), 16700: (174, 201, 255), 16800: (174, 201, 255), 16900: (174, 200, 255), 17000: (174, 200, 255), 17100: (173, 200, 255), 17200: (173, 200, 255), 17300: (173, 200, 255), 17400: (173, 200, 255), 17500: (173, 200, 255), 17600: (172, 199, 255), 17700: (172, 199, 255), 17800: (172, 199, 255), 17900: (172, 199, 255), 18000: (172, 199, 255), 18100: (171, 199, 255), 18200: (171, 199, 255), 18300: (171, 199, 255), 18400: (171, 198, 255), 18500: (171, 198, 255), 18600: (170, 198, 255), 18700: (170, 198, 255), 18800: (170, 198, 255), 18900: (170, 198, 255), 19000: (170, 198, 255), 19100: (170, 198, 255), 19200: (169, 198, 255), 19300: (169, 197, 255), 19400: (169, 197, 255), 19500: (169, 197, 255), 19600: (169, 197, 255), 19700: (169, 197, 255), 19800: (169, 197, 255), 19900: (168, 197, 255), 20000: (168, 197, 255), 20100: (168, 197, 255), 20200: (168, 197, 255), 20300: (168, 196, 255), 20400: (168, 196, 255), 20500: (168, 196, 255), 20600: (167, 196, 255), 20700: (167, 196, 255), 20800: (167, 196, 255), 20900: (167, 196, 255), 21000: (167, 196, 255), 21100: (167, 196, 255), 21200: (167, 196, 255), 21300: (166, 196, 255), 21400: (166, 195, 255), 21500: (166, 195, 255), 21600: (166, 195, 255), 21700: (166, 195, 255), 21800: (166, 195, 255), 21900: (166, 195, 255), 22000: (166, 195, 255), 22100: (165, 195, 255), 22200: (165, 195, 255), 22300: (165, 195, 255), 22400: (165, 195, 255), 22500: (165, 195, 255), 22600: (165, 195, 255), 22700: (165, 194, 255), 22800: (165, 194, 255), 22900: (165, 194, 255), 23000: (164, 194, 255), 23100: (164, 194, 255), 23200: (164, 194, 255), 23300: (164, 194, 255), 23400: (164, 194, 255), 23500: (164, 194, 255), 23600: (164, 194, 255), 23700: (164, 194, 255), 23800: (164, 194, 255), 23900: (164, 194, 255), 24000: (163, 194, 255), 24100: (163, 194, 255), 24200: (163, 193, 255), 24300: (163, 193, 255), 24400: (163, 193, 255), 24500: (163, 193, 255), 24600: (163, 193, 255), 24700: (163, 193, 255), 24800: (163, 193, 255), 24900: (163, 193, 255), 25000: (163, 193, 255), 25100: (162, 193, 255), 25200: (162, 193, 255), 25300: (162, 193, 255), 25400: (162, 193, 255), 25500: (162, 193, 255), 25600: (162, 193, 255), 25700: (162, 193, 255), 25800: (162, 193, 255), 25900: (162, 192, 255), 26000: (162, 192, 255), 26100: (162, 192, 255), 26200: (162, 192, 255), 26300: (162, 192, 255), 26400: (161, 192, 255), 26500: (161, 192, 255), 26600: (161, 192, 255), 26700: (161, 192, 255), 26800: (161, 192, 255), 26900: (161, 192, 255), 27000: (161, 192, 255), 27100: (161, 192, 255), 27200: (161, 192, 255), 27300: (161, 192, 255), 27400: (161, 192, 255), 27500: (161, 192, 255), 27600: (161, 192, 255), 27700: (161, 192, 255), 27800: (160, 192, 255), 27900: (160, 192, 255), 28000: (160, 191, 255), 28100: (160, 191, 255), 28200: (160, 191, 255), 28300: (160, 191, 255), 28400: (160, 191, 255), 28500: (160, 191, 255), 28600: (160, 191, 255), 28700: (160, 191, 255), 28800: (160, 191, 255), 28900: (160, 191, 255), 29000: (160, 191, 255), 29100: (160, 191, 255), 29200: (160, 191, 255), 29300: (159, 191, 255), 29400: (159, 191, 255), 29500: (159, 191, 255), 29600: (159, 191, 255), 29700: (159, 191, 255), 29800: (159, 191, 255), 29900: (159, 191, 255), 30000: (159, 191, 255), 30100: (159, 191, 255), 30200: (159, 191, 255), 30300: (159, 191, 255), 30400: (159, 190, 255), 30500: (159, 190, 255), 30600: (159, 190, 255), 30700: (159, 190, 255), 30800: (159, 190, 255), 30900: (159, 190, 255), 31000: (159, 190, 255), 31100: (158, 190, 255), 31200: (158, 190, 255), 31300: (158, 190, 255), 31400: (158, 190, 255), 31500: (158, 190, 255), 31600: (158, 190, 255), 31700: (158, 190, 255), 31800: (158, 190, 255), 31900: (158, 190, 255), 32000: (158, 190, 255), 32100: (158, 190, 255), 32200: (158, 190, 255), 32300: (158, 190, 255), 32400: (158, 190, 255), 32500: (158, 190, 255), 32600: (158, 190, 255), 32700: (158, 190, 255), 32800: (158, 190, 255), 32900: (158, 190, 255), 33000: (158, 190, 255), 33100: (158, 190, 255), 33200: (157, 190, 255), 33300: (157, 190, 255), 33400: (157, 189, 255), 33500: (157, 189, 255), 33600: (157, 189, 255), 33700: (157, 189, 255), 33800: (157, 189, 255), 33900: (157, 189, 255), 34000: (157, 189, 255), 34100: (157, 189, 255), 34200: (157, 189, 255), 34300: (157, 189, 255), 34400: (157, 189, 255), 34500: (157, 189, 255), 34600: (157, 189, 255), 34700: (157, 189, 255), 34800: (157, 189, 255), 34900: (157, 189, 255), 35000: (157, 189, 255), 35100: (157, 189, 255), 35200: (157, 189, 255), 35300: (157, 189, 255), 35400: (157, 189, 255), 35500: (157, 189, 255), 35600: (156, 189, 255), 35700: (156, 189, 255), 35800: (156, 189, 255), 35900: (156, 189, 255), 36000: (156, 189, 255), 36100: (156, 189, 255), 36200: (156, 189, 255), 36300: (156, 189, 255), 36400: (156, 189, 255), 36500: (156, 189, 255), 36600: (156, 189, 255), 36700: (156, 189, 255), 36800: (156, 189, 255), 36900: (156, 189, 255), 37000: (156, 189, 255), 37100: (156, 189, 255), 37200: (156, 188, 255), 37300: (156, 188, 255), 37400: (156, 188, 255), 37500: (156, 188, 255), 37600: (156, 188, 255), 37700: (156, 188, 255), 37800: (156, 188, 255), 37900: (156, 188, 255), 38000: (156, 188, 255), 38100: (156, 188, 255), 38200: (156, 188, 255), 38300: (156, 188, 255), 38400: (155, 188, 255), 38500: (155, 188, 255), 38600: (155, 188, 255), 38700: (155, 188, 255), 38800: (155, 188, 255), 38900: (155, 188, 255), 39000: (155, 188, 255), 39100: (155, 188, 255), 39200: (155, 188, 255), 39300: (155, 188, 255), 39400: (155, 188, 255), 39500: (155, 188, 255), 39600: (155, 188, 255), 39700: (155, 188, 255), 39800: (155, 188, 255), 39900: (155, 188, 255), 40000: (155, 188, 255) } def start(self): async_call(self.color.get_color, None, self.cb_color_get, self.increase_error_count) async_call(self.color.get_illuminance, None, self.cb_illuminance_get, self.increase_error_count) async_call(self.color.get_color_temperature, None, self.cb_color_temperature_get, self.increase_error_count) self.cbe_color.set_period(50) self.cbe_illuminance.set_period(100) self.cbe_color_temperature.set_period(100) async_call(self.color.get_config, None, self.cb_config, self.increase_error_count) async_call(self.color.is_light_on, None, self.cb_light_on, self.increase_error_count) self.plot_widget.stop = False self.plot_widget_illuminance.stop = False self.plot_widget_color_temperature.stop = False def stop(self): self.cbe_color.set_period(0) self.cbe_illuminance.set_period(0) self.cbe_color_temperature.set_period(0) self.plot_widget.stop = True self.plot_widget_illuminance.stop = True self.plot_widget_color_temperature.stop = True def destroy(self): pass def get_url_part(self): return 'color' @staticmethod def has_device_identifier(device_identifier): return device_identifier == BrickletColor.DEVICE_IDENTIFIER def cb_color(self, r, g, b, c): self.current_color = (r, g, b, c) self.color_label.setText(r, g, b, c) rgb_at_limit = r >= 65535 or g >= 65535 or b >= 65535 self.illuminance_label.mark_as_invalid(rgb_at_limit) self.color_temperature_label.mark_as_invalid(rgb_at_limit) # normalize = r+g+b normalize = 0xFFFF self.color_frame.set_color(r * 255.0 / normalize, g * 255.0 / normalize, b * 255.0 / normalize) def cb_illuminance(self, illuminance): self.current_illuminance = round( illuminance * 700.0 / float(self.current_gain_factor) / float(self.current_conversion_time), 1) self.illuminance_label.setText(self.current_illuminance) i = self.current_illuminance * 255 / 20000 if i > 255: i = 255 self.illuminance_frame.set_color(i, i, i) def cb_color_temperature(self, color_temperature): self.current_color_temperature = color_temperature self.color_temperature_label.setText(self.current_color_temperature) m = color_temperature % 100 color_temperature -= m if m > 50: color_temperature += 100 if color_temperature < 1000: color_temperature = 1000 if color_temperature > 40000: color_temperature = 40000 r, g, b = self.k_to_rgb[color_temperature] self.color_temperature_frame.set_color(r, g, b) def cb_light_on(self, light): self.light_checkbox.setChecked(light == BrickletColor.LIGHT_ON) def light_state_changed(self, state): if state == Qt.Checked: self.color.light_on() else: self.color.light_off() def cb_config(self, config): gain, gain_factor, conv, conv_time = self.gain_conv_to_combo( config.gain, config.integration_time) self.gain_combo.setCurrentIndex(gain) self.conversion_combo.setCurrentIndex(conv) self.current_gain_factor = gain_factor self.current_conversion_time = conv_time def gain_conv_to_combo(self, gain, conv): if gain == BrickletColor.GAIN_1X: gain = 0 gain_factor = 1 elif gain == BrickletColor.GAIN_4X: gain = 1 gain_factor = 4 elif gain == BrickletColor.GAIN_16X: gain = 2 gain_factor = 16 elif gain == BrickletColor.GAIN_60X: gain = 3 gain_factor = 60 if conv == BrickletColor.INTEGRATION_TIME_2MS: conv = 0 conv_time = 2.4 elif conv == BrickletColor.INTEGRATION_TIME_24MS: conv = 1 conv_time = 24 elif conv == BrickletColor.INTEGRATION_TIME_101MS: conv = 2 conv_time = 101 elif conv == BrickletColor.INTEGRATION_TIME_154MS: conv = 3 conv_time = 154 elif conv == BrickletColor.INTEGRATION_TIME_700MS: conv = 4 conv_time = 700 return gain, gain_factor, conv, conv_time def combo_to_gain_conv(self, gain, conv): if gain == 0: gain = BrickletColor.GAIN_1X gain_factor = 1 elif gain == 1: gain = BrickletColor.GAIN_4X gain_factor = 4 elif gain == 2: gain = BrickletColor.GAIN_16X gain_factor = 16 elif gain == 3: gain = BrickletColor.GAIN_60X gain_factor = 60 if conv == 0: conv = BrickletColor.INTEGRATION_TIME_2MS conv_time = 2.4 elif conv == 1: conv = BrickletColor.INTEGRATION_TIME_24MS conv_time = 24 elif conv == 2: conv = BrickletColor.INTEGRATION_TIME_101MS conv_time = 101 elif conv == 3: conv = BrickletColor.INTEGRATION_TIME_154MS conv_time = 154 elif conv == 4: conv = BrickletColor.INTEGRATION_TIME_700MS conv_time = 700 return gain, gain_factor, conv, conv_time def gain_changed(self, gain): conversion = self.conversion_combo.currentIndex() g, gf, c, ct = self.combo_to_gain_conv(gain, conversion) self.current_gain_factor = gf self.current_conversion_time = ct self.color.set_config(g, c) def conversion_changed(self, conversion): gain = self.gain_combo.currentIndex() g, gf, c, ct = self.combo_to_gain_conv(gain, conversion) self.current_gain_factor = gf self.current_conversion_time = ct self.color.set_config(g, c) def cb_color_get(self, color): self.cb_color(color.r, color.g, color.b, color.c) def cb_illuminance_get(self, illuminance): self.cb_illuminance(illuminance) def cb_color_temperature_get(self, color_temperature): self.cb_color_temperature(color_temperature) def get_current_r(self): return self.current_color[0] def get_current_g(self): return self.current_color[1] def get_current_b(self): return self.current_color[2] def get_current_c(self): return self.current_color[3] def get_current_illuminance_value(self): return self.current_illuminance def get_current_color_temperature_value(self): return self.current_color_temperature
class IMU(PluginBase, Ui_IMU): def __init__(self, *args): PluginBase.__init__(self, BrickIMU, *args) self.setupUi(self) self.imu = self.device # the firmware version of a Brick can (under common circumstances) not # change during the lifetime of a Brick plugin. therefore, it's okay to # make final decisions based on it here self.has_status_led = self.firmware_version >= (2, 3, 1) self.acc_x = CurveValueWrapper() self.acc_y = CurveValueWrapper() self.acc_z = CurveValueWrapper() self.mag_x = CurveValueWrapper() self.mag_y = CurveValueWrapper() self.mag_z = CurveValueWrapper() self.gyr_x = CurveValueWrapper() self.gyr_y = CurveValueWrapper() self.gyr_z = CurveValueWrapper() self.temp = CurveValueWrapper() self.roll = None self.pitch = None self.yaw = None self.qua_x = None self.qua_y = None self.qua_z = None self.qua_w = None self.all_data_valid = False self.quaternion_valid = False self.orientation_valid = False self.update_timer = QTimer(self) self.update_timer.timeout.connect(self.update_data) self.cbe_all_data = CallbackEmulator( self.imu.get_all_data, None, self.cb_all_data, self.increase_error_count, expand_result_tuple_for_callback=True, use_result_signal=False) self.cbe_orientation = CallbackEmulator( self.imu.get_orientation, None, self.cb_orientation, self.increase_error_count, expand_result_tuple_for_callback=True, use_result_signal=False) self.cbe_quaternion = CallbackEmulator( self.imu.get_quaternion, None, self.cb_quaternion, self.increase_error_count, expand_result_tuple_for_callback=True, use_result_signal=False) self.imu_gl = IMU3DWidget(self) self.imu_gl.setMinimumSize(150, 150) self.imu_gl.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.update_counter = 0 self.mag_plot_widget = PlotWidget( "Magnetic Field [µT]", [("X", Qt.red, self.mag_x, str), ("Y", Qt.darkGreen, self.mag_y, str), ("Z", Qt.blue, self.mag_z, str)], clear_button=self.clear_graphs, key='right-no-icon', y_resolution=5) self.acc_plot_widget = PlotWidget( "Acceleration [mg]", [("X", Qt.red, self.acc_x, str), ("Y", Qt.darkGreen, self.acc_y, str), ("Z", Qt.blue, self.acc_z, str)], clear_button=self.clear_graphs, key='right-no-icon', y_resolution=5) self.gyr_plot_widget = PlotWidget( "Angular Velocity [°/s]", [("X", Qt.red, self.gyr_x, str), ("Y", Qt.darkGreen, self.gyr_y, str), ("Z", Qt.blue, self.gyr_z, str)], clear_button=self.clear_graphs, key='right-no-icon', y_resolution=0.05) self.temp_plot_widget = PlotWidget("Temperature [°C]", [("t", Qt.red, self.temp, str)], clear_button=self.clear_graphs, key=None, y_resolution=0.01) self.mag_plot_widget.setMinimumSize(250, 250) self.acc_plot_widget.setMinimumSize(250, 250) self.gyr_plot_widget.setMinimumSize(250, 250) self.temp_plot_widget.setMinimumSize(250, 250) self.orientation_label = QLabel( 'Position your IMU Brick as shown in the image above, then press "Save Orientation".' ) self.orientation_label.setWordWrap(True) self.orientation_label.setAlignment(Qt.AlignHCenter) self.gl_layout = QVBoxLayout() self.gl_layout.addWidget(self.imu_gl) self.gl_layout.addWidget(self.orientation_label) self.layout_top.addWidget(self.gyr_plot_widget) self.layout_top.addWidget(self.acc_plot_widget) self.layout_top.addWidget(self.mag_plot_widget) self.layout_bottom.addLayout(self.gl_layout) self.layout_bottom.addWidget(self.temp_plot_widget) self.save_orientation.clicked.connect(self.save_orientation_clicked) self.calibrate.clicked.connect(self.calibrate_clicked) self.led_button.clicked.connect(self.led_clicked) self.speed_spinbox.editingFinished.connect(self.speed_finished) width = QFontMetrics( self.gyr_x_label.font()).boundingRect('-XXXX.X').width() self.gyr_x_label.setMinimumWidth(width) self.gyr_y_label.setMinimumWidth(width) self.gyr_z_label.setMinimumWidth(width) self.calibrate = None self.alive = True if self.has_status_led: self.status_led_action = QAction('Status LED', self) self.status_led_action.setCheckable(True) self.status_led_action.toggled.connect( lambda checked: self.imu.enable_status_led() if checked else self.imu.disable_status_led()) self.set_configs([(0, None, [self.status_led_action])]) else: self.status_led_action = None reset = QAction('Reset', self) reset.triggered.connect(self.imu.reset) self.set_actions([(0, None, [reset])]) def save_orientation_clicked(self): self.imu_gl.save_orientation() self.orientation_label.hide() def cleanup_gl(self): self.state = self.imu_gl.get_state() self.imu_gl.hide() self.imu_gl.cleanup() def restart_gl(self): self.imu_gl = IMU3DWidget() self.imu_gl.setMinimumSize(150, 150) self.imu_gl.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.gl_layout.addWidget(self.imu_gl) self.imu_gl.show() self.save_orientation.clicked.connect(self.save_orientation_clicked) self.imu_gl.set_state(self.state) def start(self): if not self.alive: return if self.has_status_led: async_call(self.imu.is_status_led_enabled, None, self.status_led_action.setChecked, self.increase_error_count) self.parent().add_callback_on_untab(lambda x: self.cleanup_gl(), 'imu_cleanup_on_untab') self.parent().add_callback_post_untab(lambda x: self.restart_gl(), 'imu_restart_post_untab') self.parent().add_callback_on_tab(lambda x: self.cleanup_gl(), 'imu_cleanup_on_tab') self.parent().add_callback_post_tab(lambda x: self.restart_gl(), 'imu_restart_post_tab') self.gl_layout.activate() self.cbe_all_data.set_period(100) self.cbe_orientation.set_period(100) self.cbe_quaternion.set_period(50) self.update_timer.start(50) async_call(self.imu.get_convergence_speed, None, self.speed_spinbox.setValue, self.increase_error_count) self.mag_plot_widget.stop = False self.acc_plot_widget.stop = False self.gyr_plot_widget.stop = False self.temp_plot_widget.stop = False def stop(self): self.mag_plot_widget.stop = True self.acc_plot_widget.stop = True self.gyr_plot_widget.stop = True self.temp_plot_widget.stop = True self.update_timer.stop() self.cbe_all_data.set_period(0) self.cbe_orientation.set_period(0) self.cbe_quaternion.set_period(0) def destroy(self): self.alive = False self.cleanup_gl() if self.calibrate: self.calibrate.close() @staticmethod def has_device_identifier(device_identifier): return device_identifier == BrickIMU.DEVICE_IDENTIFIER def cb_all_data(self, acc_x, acc_y, acc_z, mag_x, mag_y, mag_z, gyr_x, gyr_y, gyr_z, temp): self.acc_x.value = acc_x self.acc_y.value = acc_y self.acc_z.value = acc_z self.mag_x.value = mag_x / 10 self.mag_y.value = mag_y / 10 self.mag_z.value = mag_z / 10 self.gyr_x.value = gyr_x / 14.375 self.gyr_y.value = gyr_y / 14.375 self.gyr_z.value = gyr_z / 14.375 self.temp.value = temp / 100.0 self.all_data_valid = True def cb_quaternion(self, x, y, z, w): self.qua_x = x self.qua_y = y self.qua_z = z self.qua_w = w self.quaternion_valid = True def cb_orientation(self, roll, pitch, yaw): self.roll = roll / 100.0 self.pitch = pitch / 100.0 self.yaw = yaw / 100.0 self.orientation_valid = True def led_clicked(self): if 'On' in self.led_button.text().replace('&', ''): self.led_button.setText('Turn LEDs Off') self.imu.leds_on() elif 'Off' in self.led_button.text().replace('&', ''): self.led_button.setText('Turn LEDs On') self.imu.leds_off() def update_data(self): self.update_counter += 1 if self.quaternion_valid: self.imu_gl.update_orientation(self.qua_w, self.qua_x, self.qua_y, self.qua_z) if self.update_counter == 2: self.update_counter = 0 if self.all_data_valid and self.orientation_valid: self.acceleration_update(self.acc_x.value, self.acc_y.value, self.acc_z.value) self.magnetometer_update(self.mag_x.value, self.mag_y.value, self.mag_z.value) self.gyroscope_update(self.gyr_x.value, self.gyr_y.value, self.gyr_z.value) self.orientation_update(self.roll, self.pitch, self.yaw) self.temperature_update(self.temp.value) def acceleration_update(self, x, y, z): self.acc_y_label.setText(format(x, '.1f')) self.acc_x_label.setText(format(y, '.1f')) self.acc_z_label.setText(format(z, '.1f')) def magnetometer_update(self, x, y, z): # Earth magnetic field: 0.5 Gauss self.mag_x_label.setText(format(x, '.1f')) self.mag_y_label.setText(format(y, '.1f')) self.mag_z_label.setText(format(z, '.1f')) def gyroscope_update(self, x, y, z): self.gyr_x_label.setText(format(x, '.1f')) self.gyr_y_label.setText(format(y, '.1f')) self.gyr_z_label.setText(format(z, '.1f')) def orientation_update(self, r, p, y): self.roll_label.setText(format(r, '.1f')) self.pitch_label.setText(format(p, '.1f')) self.yaw_label.setText(format(y, '.1f')) def temperature_update(self, t): self.tem_label.setText(format(t, '.1f')) def calibrate_clicked(self): self.stop() if self.calibrate is None: self.calibrate = CalibrateWindow(self) self.calibrate.refresh_values() self.calibrate.show() def speed_finished(self): speed = self.speed_spinbox.value() self.imu.set_convergence_speed(speed)
class ColorV2(COMCUPluginBase): def __init__(self, *args): super().__init__(BrickletColorV2, *args) self.color = self.device self.cbe_color = CallbackEmulator(self.color.get_color, None, self.cb_color, self.increase_error_count, expand_result_tuple_for_callback=True) self.cbe_illuminance = CallbackEmulator(self.color.get_illuminance, None, self.cb_illuminance, self.increase_error_count) self.cbe_color_temperature = CallbackEmulator(self.color.get_color_temperature, None, self.cb_color_temperature, self.increase_error_count) self.color_frame = ColorFrame() self.illuminance_frame = ColorFrame() self.color_temperature_frame = ColorFrame() self.current_color_r = CurveValueWrapper() # int self.current_color_g = CurveValueWrapper() # int self.current_color_b = CurveValueWrapper() # int self.current_color_c = CurveValueWrapper() # int self.current_illuminance = CurveValueWrapper() # float, lx self.current_color_temperature = CurveValueWrapper() # int, K self.clear_graphs_button = QPushButton("Clear Graphs") plots = [('R', Qt.red, self.current_color_r, lambda value: self.format_color(0, value)), ('G', Qt.darkGreen, self.current_color_g, lambda value: self.format_color(1, value)), ('B', Qt.blue, self.current_color_b, lambda value: self.format_color(2, value)), ('C', Qt.black, self.current_color_c, str)] self.plot_widget = PlotWidget('Color', plots, clear_button=self.clear_graphs_button, extra_key_widgets=[self.color_frame], y_resolution=1.0) self.plot_widget.setMinimumSize(250, 200) plots_illuminance = [('Illuminance', Qt.red, self.current_illuminance, '{} lx (Lux)'.format)] self.plot_widget_illuminance = PlotWidget('Illuminance [lx]', plots_illuminance, clear_button=self.clear_graphs_button, extra_key_widgets=[self.illuminance_frame], y_resolution=0.1) self.plot_widget_illuminance.setMinimumSize(250, 200) plots_color_temperature = [('Color Temperature', Qt.red, self.current_color_temperature, '{} K'.format)] self.plot_widget_color_temperature = PlotWidget('Color Temperature [K]', plots_color_temperature, clear_button=self.clear_graphs_button, extra_key_widgets=[self.color_temperature_frame], y_resolution=1.0) self.plot_widget_color_temperature.setMinimumSize(250, 200) self.gain_label = QLabel('Gain:') self.gain_combo = QComboBox() self.gain_combo.addItem("1x") self.gain_combo.addItem("4x") self.gain_combo.addItem("16x") self.gain_combo.addItem("60x") self.gain_combo.currentIndexChanged.connect(self.gain_changed) self.current_gain_factor = 60 self.conversion_label = QLabel('Integration Time:') self.conversion_combo = QComboBox() self.conversion_combo.addItem("2.4 ms") self.conversion_combo.addItem("24 ms") self.conversion_combo.addItem("101 ms") self.conversion_combo.addItem("154 ms") self.conversion_combo.addItem("700 ms") self.current_conversion_time = 154 self.conversion_combo.currentIndexChanged.connect(self.conversion_changed) self.light_checkbox = QCheckBox("Enable Light") self.light_checkbox.stateChanged.connect(self.light_state_changed) layout_h1 = QHBoxLayout() layout_h1.addWidget(self.plot_widget_illuminance) layout_h1.addWidget(self.plot_widget_color_temperature) layout_h2 = QHBoxLayout() layout_h2.addWidget(self.gain_label) layout_h2.addWidget(self.gain_combo) layout_h2.addWidget(self.conversion_label) layout_h2.addWidget(self.conversion_combo) layout_h2.addWidget(self.light_checkbox) layout_h2.addStretch() layout_h2.addWidget(self.clear_graphs_button) line1 = QFrame() line1.setObjectName("line1") line1.setFrameShape(QFrame.HLine) line1.setFrameShadow(QFrame.Sunken) line2 = QFrame() line2.setObjectName("line2") line2.setFrameShape(QFrame.HLine) line2.setFrameShadow(QFrame.Sunken) layout = QVBoxLayout(self) layout.addWidget(self.plot_widget) layout.addWidget(line1) layout.addLayout(layout_h1) layout.addWidget(line2) layout.addLayout(layout_h2) self.k_to_rgb = {1000:(255, 56, 0), 1100:(255, 71, 0), 1200:(255, 83, 0), 1300:(255, 93, 0), 1400:(255, 101, 0), 1500:(255, 109, 0), 1600:(255, 115, 0), 1700:(255, 121, 0), 1800:(255, 126, 0), 1900:(255, 131, 0), 2000:(255, 137, 18), 2100:(255, 142, 33), 2200:(255, 147, 44), 2300:(255, 152, 54), 2400:(255, 157, 63), 2500:(255, 161, 72), 2600:(255, 165, 79), 2700:(255, 169, 87), 2800:(255, 173, 94), 2900:(255, 177, 101), 3000:(255, 180, 107), 3100:(255, 184, 114), 3200:(255, 187, 120), 3300:(255, 190, 126), 3400:(255, 193, 132), 3500:(255, 196, 137), 3600:(255, 199, 143), 3700:(255, 201, 148), 3800:(255, 204, 153), 3900:(255, 206, 159), 4000:(255, 209, 163), 4100:(255, 211, 168), 4200:(255, 213, 173), 4300:(255, 215, 177), 4400:(255, 217, 182), 4500:(255, 219, 186), 4600:(255, 221, 190), 4700:(255, 223, 194), 4800:(255, 225, 198), 4900:(255, 227, 202), 5000:(255, 228, 206), 5100:(255, 230, 210), 5200:(255, 232, 213), 5300:(255, 233, 217), 5400:(255, 235, 220), 5500:(255, 236, 224), 5600:(255, 238, 227), 5700:(255, 239, 230), 5800:(255, 240, 233), 5900:(255, 242, 236), 6000:(255, 243, 239), 6100:(255, 244, 242), 6200:(255, 245, 245), 6300:(255, 246, 248), 6400:(255, 248, 251), 6500:(255, 249, 253), 6600:(254, 249, 255), 6700:(252, 247, 255), 6800:(249, 246, 255), 6900:(247, 245, 255), 7000:(245, 243, 255), 7100:(243, 242, 255), 7200:(240, 241, 255), 7300:(239, 240, 255), 7400:(237, 239, 255), 7500:(235, 238, 255), 7600:(233, 237, 255), 7700:(231, 236, 255), 7800:(230, 235, 255), 7900:(228, 234, 255), 8000:(227, 233, 255), 8100:(225, 232, 255), 8200:(224, 231, 255), 8300:(222, 230, 255), 8400:(221, 230, 255), 8500:(220, 229, 255), 8600:(218, 228, 255), 8700:(217, 227, 255), 8800:(216, 227, 255), 8900:(215, 226, 255), 9000:(214, 225, 255), 9100:(212, 225, 255), 9200:(211, 224, 255), 9300:(210, 223, 255), 9400:(209, 223, 255), 9500:(208, 222, 255), 9600:(207, 221, 255), 9700:(207, 221, 255), 9800:(206, 220, 255), 9900:(205, 220, 255), 10000:(204, 219, 255), 10100:(203, 219, 255), 10200:(202, 218, 255), 10300:(201, 218, 255), 10400:(201, 217, 255), 10500:(200, 217, 255), 10600:(199, 216, 255), 10700:(199, 216, 255), 10800:(198, 216, 255), 10900:(197, 215, 255), 11000:(196, 215, 255), 11100:(196, 214, 255), 11200:(195, 214, 255), 11300:(195, 214, 255), 11400:(194, 213, 255), 11500:(193, 213, 255), 11600:(193, 212, 255), 11700:(192, 212, 255), 11800:(192, 212, 255), 11900:(191, 211, 255), 12000:(191, 211, 255), 12100:(190, 211, 255), 12200:(190, 210, 255), 12300:(189, 210, 255), 12400:(189, 210, 255), 12500:(188, 210, 255), 12600:(188, 209, 255), 12700:(187, 209, 255), 12800:(187, 209, 255), 12900:(186, 208, 255), 13000:(186, 208, 255), 13100:(185, 208, 255), 13200:(185, 208, 255), 13300:(185, 207, 255), 13400:(184, 207, 255), 13500:(184, 207, 255), 13600:(183, 207, 255), 13700:(183, 206, 255), 13800:(183, 206, 255), 13900:(182, 206, 255), 14000:(182, 206, 255), 14100:(182, 205, 255), 14200:(181, 205, 255), 14300:(181, 205, 255), 14400:(181, 205, 255), 14500:(180, 205, 255), 14600:(180, 204, 255), 14700:(180, 204, 255), 14800:(179, 204, 255), 14900:(179, 204, 255), 15000:(179, 204, 255), 15100:(178, 203, 255), 15200:(178, 203, 255), 15300:(178, 203, 255), 15400:(178, 203, 255), 15500:(177, 203, 255), 15600:(177, 202, 255), 15700:(177, 202, 255), 15800:(177, 202, 255), 15900:(176, 202, 255), 16000:(176, 202, 255), 16100:(176, 202, 255), 16200:(175, 201, 255), 16300:(175, 201, 255), 16400:(175, 201, 255), 16500:(175, 201, 255), 16600:(175, 201, 255), 16700:(174, 201, 255), 16800:(174, 201, 255), 16900:(174, 200, 255), 17000:(174, 200, 255), 17100:(173, 200, 255), 17200:(173, 200, 255), 17300:(173, 200, 255), 17400:(173, 200, 255), 17500:(173, 200, 255), 17600:(172, 199, 255), 17700:(172, 199, 255), 17800:(172, 199, 255), 17900:(172, 199, 255), 18000:(172, 199, 255), 18100:(171, 199, 255), 18200:(171, 199, 255), 18300:(171, 199, 255), 18400:(171, 198, 255), 18500:(171, 198, 255), 18600:(170, 198, 255), 18700:(170, 198, 255), 18800:(170, 198, 255), 18900:(170, 198, 255), 19000:(170, 198, 255), 19100:(170, 198, 255), 19200:(169, 198, 255), 19300:(169, 197, 255), 19400:(169, 197, 255), 19500:(169, 197, 255), 19600:(169, 197, 255), 19700:(169, 197, 255), 19800:(169, 197, 255), 19900:(168, 197, 255), 20000:(168, 197, 255), 20100:(168, 197, 255), 20200:(168, 197, 255), 20300:(168, 196, 255), 20400:(168, 196, 255), 20500:(168, 196, 255), 20600:(167, 196, 255), 20700:(167, 196, 255), 20800:(167, 196, 255), 20900:(167, 196, 255), 21000:(167, 196, 255), 21100:(167, 196, 255), 21200:(167, 196, 255), 21300:(166, 196, 255), 21400:(166, 195, 255), 21500:(166, 195, 255), 21600:(166, 195, 255), 21700:(166, 195, 255), 21800:(166, 195, 255), 21900:(166, 195, 255), 22000:(166, 195, 255), 22100:(165, 195, 255), 22200:(165, 195, 255), 22300:(165, 195, 255), 22400:(165, 195, 255), 22500:(165, 195, 255), 22600:(165, 195, 255), 22700:(165, 194, 255), 22800:(165, 194, 255), 22900:(165, 194, 255), 23000:(164, 194, 255), 23100:(164, 194, 255), 23200:(164, 194, 255), 23300:(164, 194, 255), 23400:(164, 194, 255), 23500:(164, 194, 255), 23600:(164, 194, 255), 23700:(164, 194, 255), 23800:(164, 194, 255), 23900:(164, 194, 255), 24000:(163, 194, 255), 24100:(163, 194, 255), 24200:(163, 193, 255), 24300:(163, 193, 255), 24400:(163, 193, 255), 24500:(163, 193, 255), 24600:(163, 193, 255), 24700:(163, 193, 255), 24800:(163, 193, 255), 24900:(163, 193, 255), 25000:(163, 193, 255), 25100:(162, 193, 255), 25200:(162, 193, 255), 25300:(162, 193, 255), 25400:(162, 193, 255), 25500:(162, 193, 255), 25600:(162, 193, 255), 25700:(162, 193, 255), 25800:(162, 193, 255), 25900:(162, 192, 255), 26000:(162, 192, 255), 26100:(162, 192, 255), 26200:(162, 192, 255), 26300:(162, 192, 255), 26400:(161, 192, 255), 26500:(161, 192, 255), 26600:(161, 192, 255), 26700:(161, 192, 255), 26800:(161, 192, 255), 26900:(161, 192, 255), 27000:(161, 192, 255), 27100:(161, 192, 255), 27200:(161, 192, 255), 27300:(161, 192, 255), 27400:(161, 192, 255), 27500:(161, 192, 255), 27600:(161, 192, 255), 27700:(161, 192, 255), 27800:(160, 192, 255), 27900:(160, 192, 255), 28000:(160, 191, 255), 28100:(160, 191, 255), 28200:(160, 191, 255), 28300:(160, 191, 255), 28400:(160, 191, 255), 28500:(160, 191, 255), 28600:(160, 191, 255), 28700:(160, 191, 255), 28800:(160, 191, 255), 28900:(160, 191, 255), 29000:(160, 191, 255), 29100:(160, 191, 255), 29200:(160, 191, 255), 29300:(159, 191, 255), 29400:(159, 191, 255), 29500:(159, 191, 255), 29600:(159, 191, 255), 29700:(159, 191, 255), 29800:(159, 191, 255), 29900:(159, 191, 255), 30000:(159, 191, 255), 30100:(159, 191, 255), 30200:(159, 191, 255), 30300:(159, 191, 255), 30400:(159, 190, 255), 30500:(159, 190, 255), 30600:(159, 190, 255), 30700:(159, 190, 255), 30800:(159, 190, 255), 30900:(159, 190, 255), 31000:(159, 190, 255), 31100:(158, 190, 255), 31200:(158, 190, 255), 31300:(158, 190, 255), 31400:(158, 190, 255), 31500:(158, 190, 255), 31600:(158, 190, 255), 31700:(158, 190, 255), 31800:(158, 190, 255), 31900:(158, 190, 255), 32000:(158, 190, 255), 32100:(158, 190, 255), 32200:(158, 190, 255), 32300:(158, 190, 255), 32400:(158, 190, 255), 32500:(158, 190, 255), 32600:(158, 190, 255), 32700:(158, 190, 255), 32800:(158, 190, 255), 32900:(158, 190, 255), 33000:(158, 190, 255), 33100:(158, 190, 255), 33200:(157, 190, 255), 33300:(157, 190, 255), 33400:(157, 189, 255), 33500:(157, 189, 255), 33600:(157, 189, 255), 33700:(157, 189, 255), 33800:(157, 189, 255), 33900:(157, 189, 255), 34000:(157, 189, 255), 34100:(157, 189, 255), 34200:(157, 189, 255), 34300:(157, 189, 255), 34400:(157, 189, 255), 34500:(157, 189, 255), 34600:(157, 189, 255), 34700:(157, 189, 255), 34800:(157, 189, 255), 34900:(157, 189, 255), 35000:(157, 189, 255), 35100:(157, 189, 255), 35200:(157, 189, 255), 35300:(157, 189, 255), 35400:(157, 189, 255), 35500:(157, 189, 255), 35600:(156, 189, 255), 35700:(156, 189, 255), 35800:(156, 189, 255), 35900:(156, 189, 255), 36000:(156, 189, 255), 36100:(156, 189, 255), 36200:(156, 189, 255), 36300:(156, 189, 255), 36400:(156, 189, 255), 36500:(156, 189, 255), 36600:(156, 189, 255), 36700:(156, 189, 255), 36800:(156, 189, 255), 36900:(156, 189, 255), 37000:(156, 189, 255), 37100:(156, 189, 255), 37200:(156, 188, 255), 37300:(156, 188, 255), 37400:(156, 188, 255), 37500:(156, 188, 255), 37600:(156, 188, 255), 37700:(156, 188, 255), 37800:(156, 188, 255), 37900:(156, 188, 255), 38000:(156, 188, 255), 38100:(156, 188, 255), 38200:(156, 188, 255), 38300:(156, 188, 255), 38400:(155, 188, 255), 38500:(155, 188, 255), 38600:(155, 188, 255), 38700:(155, 188, 255), 38800:(155, 188, 255), 38900:(155, 188, 255), 39000:(155, 188, 255), 39100:(155, 188, 255), 39200:(155, 188, 255), 39300:(155, 188, 255), 39400:(155, 188, 255), 39500:(155, 188, 255), 39600:(155, 188, 255), 39700:(155, 188, 255), 39800:(155, 188, 255), 39900:(155, 188, 255), 40000:(155, 188, 255)} def start(self): async_call(self.color.get_config, None, self.get_config_async, self.increase_error_count) async_call(self.color.get_light, None, self.get_light_async, self.increase_error_count) self.cbe_color.set_period(50) self.cbe_illuminance.set_period(100) self.cbe_color_temperature.set_period(100) self.plot_widget.stop = False self.plot_widget_illuminance.stop = False self.plot_widget_color_temperature.stop = False def stop(self): self.cbe_color.set_period(0) self.cbe_illuminance.set_period(0) self.cbe_color_temperature.set_period(0) self.plot_widget.stop = True self.plot_widget_illuminance.stop = True self.plot_widget_color_temperature.stop = True def destroy(self): pass @staticmethod def has_device_identifier(device_identifier): return device_identifier == BrickletColorV2.DEVICE_IDENTIFIER def format_color(self, i, value): if value >= 65535: self.plot_widget.get_key_item(i).setStyleSheet('QToolButton { color: red }') else: self.plot_widget.get_key_item(i).setStyleSheet('') return str(value) def cb_color(self, r, g, b, c): self.current_color_r.value = r self.current_color_g.value = g self.current_color_b.value = b self.current_color_c.value = c if r >= 65535 or g >= 65535 or b >= 65535: self.plot_widget_illuminance.get_key_item(0).setStyleSheet('QLabel { color: red }') self.plot_widget_color_temperature.get_key_item(0).setStyleSheet('QLabel { color: red }') else: self.plot_widget_illuminance.get_key_item(0).setStyleSheet('') self.plot_widget_color_temperature.get_key_item(0).setStyleSheet('') normalize = 0xFFFF self.color_frame.set_color(r * 255 // normalize, g * 255 // normalize, b * 255 // normalize) def cb_illuminance(self, illuminance): self.current_illuminance.value = round(illuminance * 700.0 / self.current_gain_factor / self.current_conversion_time, 1) i = int(self.current_illuminance.value) * 255 // 20000 if i > 255: i = 255 self.illuminance_frame.set_color(i, i, i) def cb_color_temperature(self, color_temperature): self.current_color_temperature.value = color_temperature m = color_temperature % 100 color_temperature -= m if m > 50: color_temperature += 100 if color_temperature < 1000: color_temperature = 1000 if color_temperature > 40000: color_temperature = 40000 r, g, b = self.k_to_rgb[color_temperature] self.color_temperature_frame.set_color(r, g, b) def get_light_async(self, enable): self.light_checkbox.setChecked(enable) def light_state_changed(self, state): self.color.set_light(state == Qt.Checked) def get_config_async(self, config): gain, gain_factor, conv, conv_time = self.gain_conv_to_combo(config.gain, config.integration_time) self.gain_combo.setCurrentIndex(gain) self.conversion_combo.setCurrentIndex(conv) self.current_gain_factor = gain_factor self.current_conversion_time = conv_time def gain_conv_to_combo(self, gain, conv): if gain == BrickletColorV2.GAIN_1X: gain = 0 gain_factor = 1 elif gain == BrickletColorV2.GAIN_4X: gain = 1 gain_factor = 4 elif gain == BrickletColorV2.GAIN_16X: gain = 2 gain_factor = 16 elif gain == BrickletColorV2.GAIN_60X: gain = 3 gain_factor = 60 if conv == BrickletColorV2.INTEGRATION_TIME_2MS: conv = 0 conv_time = 2.4 elif conv == BrickletColorV2.INTEGRATION_TIME_24MS: conv = 1 conv_time = 24 elif conv == BrickletColorV2.INTEGRATION_TIME_101MS: conv = 2 conv_time = 101 elif conv == BrickletColorV2.INTEGRATION_TIME_154MS: conv = 3 conv_time = 154 elif conv == BrickletColorV2.INTEGRATION_TIME_700MS: conv = 4 conv_time = 700 return gain, gain_factor, conv, conv_time def combo_to_gain_conv(self, gain, conv): if gain == 0: gain = BrickletColorV2.GAIN_1X gain_factor = 1 elif gain == 1: gain = BrickletColorV2.GAIN_4X gain_factor = 4 elif gain == 2: gain = BrickletColorV2.GAIN_16X gain_factor = 16 elif gain == 3: gain = BrickletColorV2.GAIN_60X gain_factor = 60 if conv == 0: conv = BrickletColorV2.INTEGRATION_TIME_2MS conv_time = 2.4 elif conv == 1: conv = BrickletColorV2.INTEGRATION_TIME_24MS conv_time = 24 elif conv == 2: conv = BrickletColorV2.INTEGRATION_TIME_101MS conv_time = 101 elif conv == 3: conv = BrickletColorV2.INTEGRATION_TIME_154MS conv_time = 154 elif conv == 4: conv = BrickletColorV2.INTEGRATION_TIME_700MS conv_time = 700 return gain, gain_factor, conv, conv_time def gain_changed(self, gain): conversion = self.conversion_combo.currentIndex() g, gf, c, ct = self.combo_to_gain_conv(gain, conversion) self.current_gain_factor = gf self.current_conversion_time = ct self.color.set_config(g, c) def conversion_changed(self, conversion): gain = self.gain_combo.currentIndex() g, gf, c, ct = self.combo_to_gain_conv(gain, conversion) self.current_gain_factor = gf self.current_conversion_time = ct self.color.set_config(g, c)