diff --git a/cgv_connector.proto b/cgv_connector.proto index be68b973f8c82c5b99b10e7fefcbbf4c05bb4c5d..ca2f8c48e61b1d433d5322894dac851cfb6491af 100644 --- a/cgv_connector.proto +++ b/cgv_connector.proto @@ -37,6 +37,7 @@ message Object { BOX = 1; BIN = 2; ARM = 3; + DROP_OFF_LOCATION = 4; } string id = 1; @@ -72,4 +73,4 @@ message Reachability { } string idRobot = 1; // the id of the robot arm repeated ObjectReachability objects = 2; // all objects reachable -} +} \ No newline at end of file diff --git a/cgv_connector_pb2.py b/cgv_connector_pb2.py index 932342232a014ab704691d1f27d868531b3a3f9a..2ae9aa98a1ca38ec9271e5be266d41ed9493fa70 100644 --- a/cgv_connector_pb2.py +++ b/cgv_connector_pb2.py @@ -19,7 +19,7 @@ DESCRIPTOR = _descriptor.FileDescriptor( syntax='proto3', serialized_options=b'\n\030de.tudresden.inf.st.cetiP\001', create_key=_descriptor._internal_create_key, - serialized_pb=b'\n\x13\x63gv_connector.proto\"\xac\x03\n\x06Object\x12\n\n\x02id\x18\x01 \x01(\t\x12\x1a\n\x04type\x18\x02 \x01(\x0e\x32\x0c.Object.Type\x12\x1d\n\x03pos\x18\x03 \x01(\x0b\x32\x10.Object.Position\x12\x1a\n\x04size\x18\x04 \x01(\x0b\x32\x0c.Object.Size\x12(\n\x0borientation\x18\x05 \x01(\x0b\x32\x13.Object.Orientation\x12\x1c\n\x05\x63olor\x18\x06 \x01(\x0b\x32\r.Object.Color\x1a+\n\x08Position\x12\t\n\x01x\x18\x01 \x01(\x02\x12\t\n\x01y\x18\x02 \x01(\x02\x12\t\n\x01z\x18\x03 \x01(\x02\x1a\x35\n\x04Size\x12\x0e\n\x06length\x18\x01 \x01(\x02\x12\r\n\x05width\x18\x02 \x01(\x02\x12\x0e\n\x06height\x18\x03 \x01(\x02\x1a\x39\n\x0bOrientation\x12\t\n\x01x\x18\x01 \x01(\x02\x12\t\n\x01y\x18\x02 \x01(\x02\x12\t\n\x01z\x18\x03 \x01(\x02\x12\t\n\x01w\x18\x04 \x01(\x02\x1a(\n\x05\x43olor\x12\t\n\x01r\x18\x01 \x01(\x02\x12\t\n\x01g\x18\x02 \x01(\x02\x12\t\n\x01\x62\x18\x03 \x01(\x02\".\n\x04Type\x12\x0b\n\x07UNKNOWN\x10\x00\x12\x07\n\x03\x42OX\x10\x01\x12\x07\n\x03\x42IN\x10\x02\x12\x07\n\x03\x41RM\x10\x03\"!\n\x05Scene\x12\x18\n\x07objects\x18\x01 \x03(\x0b\x32\x07.Object\"\x17\n\tSelection\x12\n\n\x02id\x18\x01 \x01(\t\"C\n\x0fMergedSelection\x12\x0f\n\x07idRobot\x18\x01 \x01(\t\x12\x0e\n\x06idPick\x18\x02 \x01(\t\x12\x0f\n\x07idPlace\x18\x03 \x01(\t\"\x8d\x01\n\x0cReachability\x12\x0f\n\x07idRobot\x18\x01 \x01(\t\x12\x31\n\x07objects\x18\x02 \x03(\x0b\x32 .Reachability.ObjectReachability\x1a\x39\n\x12ObjectReachability\x12\x10\n\x08idObject\x18\x01 \x01(\t\x12\x11\n\treachable\x18\x02 \x01(\x08\x42\x1c\n\x18\x64\x65.tudresden.inf.st.cetiP\x01\x62\x06proto3' + serialized_pb=b'\n\x13\x63gv_connector.proto\"\xc3\x03\n\x06Object\x12\n\n\x02id\x18\x01 \x01(\t\x12\x1a\n\x04type\x18\x02 \x01(\x0e\x32\x0c.Object.Type\x12\x1d\n\x03pos\x18\x03 \x01(\x0b\x32\x10.Object.Position\x12\x1a\n\x04size\x18\x04 \x01(\x0b\x32\x0c.Object.Size\x12(\n\x0borientation\x18\x05 \x01(\x0b\x32\x13.Object.Orientation\x12\x1c\n\x05\x63olor\x18\x06 \x01(\x0b\x32\r.Object.Color\x1a+\n\x08Position\x12\t\n\x01x\x18\x01 \x01(\x02\x12\t\n\x01y\x18\x02 \x01(\x02\x12\t\n\x01z\x18\x03 \x01(\x02\x1a\x35\n\x04Size\x12\x0e\n\x06length\x18\x01 \x01(\x02\x12\r\n\x05width\x18\x02 \x01(\x02\x12\x0e\n\x06height\x18\x03 \x01(\x02\x1a\x39\n\x0bOrientation\x12\t\n\x01x\x18\x01 \x01(\x02\x12\t\n\x01y\x18\x02 \x01(\x02\x12\t\n\x01z\x18\x03 \x01(\x02\x12\t\n\x01w\x18\x04 \x01(\x02\x1a(\n\x05\x43olor\x12\t\n\x01r\x18\x01 \x01(\x02\x12\t\n\x01g\x18\x02 \x01(\x02\x12\t\n\x01\x62\x18\x03 \x01(\x02\"E\n\x04Type\x12\x0b\n\x07UNKNOWN\x10\x00\x12\x07\n\x03\x42OX\x10\x01\x12\x07\n\x03\x42IN\x10\x02\x12\x07\n\x03\x41RM\x10\x03\x12\x15\n\x11\x44ROP_OFF_LOCATION\x10\x04\"!\n\x05Scene\x12\x18\n\x07objects\x18\x01 \x03(\x0b\x32\x07.Object\"\x17\n\tSelection\x12\n\n\x02id\x18\x01 \x01(\t\"C\n\x0fMergedSelection\x12\x0f\n\x07idRobot\x18\x01 \x01(\t\x12\x0e\n\x06idPick\x18\x02 \x01(\t\x12\x0f\n\x07idPlace\x18\x03 \x01(\t\"\x8d\x01\n\x0cReachability\x12\x0f\n\x07idRobot\x18\x01 \x01(\t\x12\x31\n\x07objects\x18\x02 \x03(\x0b\x32 .Reachability.ObjectReachability\x1a\x39\n\x12ObjectReachability\x12\x10\n\x08idObject\x18\x01 \x01(\t\x12\x11\n\treachable\x18\x02 \x01(\x08\x42\x1c\n\x18\x64\x65.tudresden.inf.st.cetiP\x01\x62\x06proto3' ) @@ -51,11 +51,16 @@ _OBJECT_TYPE = _descriptor.EnumDescriptor( serialized_options=None, type=None, create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='DROP_OFF_LOCATION', index=4, number=4, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), ], containing_type=None, serialized_options=None, serialized_start=406, - serialized_end=452, + serialized_end=475, ) _sym_db.RegisterEnumDescriptor(_OBJECT_TYPE) @@ -311,7 +316,7 @@ _OBJECT = _descriptor.Descriptor( oneofs=[ ], serialized_start=24, - serialized_end=452, + serialized_end=475, ) @@ -342,8 +347,8 @@ _SCENE = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=454, - serialized_end=487, + serialized_start=477, + serialized_end=510, ) @@ -374,8 +379,8 @@ _SELECTION = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=489, - serialized_end=512, + serialized_start=512, + serialized_end=535, ) @@ -420,8 +425,8 @@ _MERGEDSELECTION = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=514, - serialized_end=581, + serialized_start=537, + serialized_end=604, ) @@ -459,8 +464,8 @@ _REACHABILITY_OBJECTREACHABILITY = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=668, - serialized_end=725, + serialized_start=691, + serialized_end=748, ) _REACHABILITY = _descriptor.Descriptor( @@ -497,8 +502,8 @@ _REACHABILITY = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=584, - serialized_end=725, + serialized_start=607, + serialized_end=748, ) _OBJECT_POSITION.containing_type = _OBJECT diff --git a/config/config-scene-a.json b/config/config-scene-a.json index 9f09d081b7d6caa749305865649366b180d27286..6f2c1bb2d5fab527596ed91da4bcac3465e36bd8 100644 --- a/config/config-scene-a.json +++ b/config/config-scene-a.json @@ -4,9 +4,9 @@ { "id": "tablePillar3","pos": { "x": -0.77,"y": 0.77,"z": 0.325 },"size": { "length": 0.06,"width": 0.06,"height": 0.65 },"orientation": { "w": 1 },"color": { "r": 255,"g": 222,"b": 173 } }, { "id": "tablePillar4","pos": { "x": 0.77,"y": -0.77,"z": 0.325 },"size": { "length": 0.06,"width": 0.06,"height": 0.65 },"orientation": { "w": 1 },"color": { "r": 255,"g": 222,"b": 173 } }, { "id": "table","pos": { "z": 0.7 },"size": { "length": 1.6,"width": 1.6,"height": 0.1 },"orientation": { "w": 1 },"color": { "r": 255,"g": 222,"b": 173 } }, - { "id": "binBlue","type": "BIN","pos": { "x": -0.34,"y": 0.49,"z": 0.8325 },"size": { "length": 0.21,"width": 0.3,"height": 0.165 },"orientation": { "w": 1 },"color": { "b": 1 } }, - { "id": "binRed","type": "BIN","pos": { "x": 0.06,"y": 0.49,"z": 0.8325 },"size": { "length": 0.21,"width": 0.3,"height": 0.165 },"orientation": { "w": 1 },"color": { "r": 1 } }, - { "id": "binGreen","type": "BIN","pos": { "x": 0.46,"y": 0.49,"z": 0.8325 },"size": { "length": 0.21,"width": 0.3,"height": 0.165 },"orientation": { "w": 1 },"color": { "g": 1 } }, + { "id": "binBlue","type": "DROP_OFF_LOCATION","pos": { "x": -0.34,"y": 0.49,"z": 0.8325 },"size": { "length": 0.21,"width": 0.3,"height": 0.165 },"orientation": { "w": 1 },"color": { "b": 1 } }, + { "id": "binRed","type": "DROP_OFF_LOCATION","pos": { "x": 0.06,"y": 0.49,"z": 0.8325 },"size": { "length": 0.21,"width": 0.3,"height": 0.165 },"orientation": { "w": 1 },"color": { "r": 1 } }, + { "id": "binGreen","type": "DROP_OFF_LOCATION","pos": { "x": 0.46,"y": 0.49,"z": 0.8325 },"size": { "length": 0.21,"width": 0.3,"height": 0.165 },"orientation": { "w": 1 },"color": { "g": 1 } }, { "id": "objectRed1","type": "BOX","pos": { "x": 0.5,"y": -0.1,"z": 0.8105 },"size": { "length": 0.031,"width": 0.062,"height": 0.121 },"orientation": { "z": 0.382683,"w": 0.92388 },"color": { "r": 1 } }, { "id": "objectRed2","type": "BOX","pos": { "x": 0.25,"y": -0.2,"z": 0.8105 },"size": { "length": 0.031,"width": 0.062,"height": 0.121 },"orientation": { "w": 1 },"color": { "r": 1 } }, { "id": "objectRed3","type": "BOX","pos": { "x": -0.4,"z": 0.819 },"size": { "length": 0.031,"width": 0.031,"height": 0.138 },"orientation": { "z": 0.382683,"w": 0.92388 },"color": { "r": 1 } }, diff --git a/config/config-scene-b.json b/config/config-scene-b.json index f14e17fe05da23db662d514b49ae47d406a0ddd4..b67a78c89fb491c4c7aacdb566c3301a89dbdf18 100644 --- a/config/config-scene-b.json +++ b/config/config-scene-b.json @@ -4,9 +4,9 @@ { "id": "tablePillar3","pos": { "x": -0.77,"y": 0.77,"z": 0.325 },"size": { "length": 0.06,"width": 0.06,"height": 0.65 },"orientation": { "w": 1 },"color": { "r": 255,"g": 222,"b": 173 } }, { "id": "tablePillar4","pos": { "x": 0.77,"y": -0.77,"z": 0.325 },"size": { "length": 0.06,"width": 0.06,"height": 0.65 },"orientation": { "w": 1 },"color": { "r": 255,"g": 222,"b": 173 } }, { "id": "table","pos": { "z": 0.7 },"size": { "length": 1.6,"width": 1.6,"height": 0.1 },"orientation": { "w": 1 },"color": { "r": 255,"g": 222,"b": 173 } }, - { "id": "binBlue","type": "BIN","pos": { "x": -0.34,"y": 0.49,"z": 0.8325 },"size": { "length": 0.21,"width": 0.3,"height": 0.165 },"orientation": { "w": 1 },"color": { "b": 1 } }, - { "id": "binRed","type": "BIN","pos": { "x": 0.06,"y": 0.49,"z": 0.8325 },"size": { "length": 0.21,"width": 0.3,"height": 0.165 },"orientation": { "w": 1 },"color": { "r": 1 } }, - { "id": "binGreen","type": "BIN","pos": { "x": 0.46,"y": 0.49,"z": 0.8325 },"size": { "length": 0.21,"width": 0.3,"height": 0.165 },"orientation": { "w": 1 },"color": { "g": 1 } }, + { "id": "binBlue","type": "DROP_OFF_LOCATION","pos": { "x": -0.34,"y": 0.49,"z": 0.8325 },"size": { "length": 0.21,"width": 0.3,"height": 0.165 },"orientation": { "w": 1 },"color": { "b": 1 } }, + { "id": "binRed","type": "DROP_OFF_LOCATION","pos": { "x": 0.06,"y": 0.49,"z": 0.8325 },"size": { "length": 0.21,"width": 0.3,"height": 0.165 },"orientation": { "w": 1 },"color": { "r": 1 } }, + { "id": "binGreen","type": "DROP_OFF_LOCATION","pos": { "x": 0.46,"y": 0.49,"z": 0.8325 },"size": { "length": 0.21,"width": 0.3,"height": 0.165 },"orientation": { "w": 1 },"color": { "g": 1 } }, { "id": "objectRed1","type": "BOX","pos": { "x": 0.5,"y": -0.1,"z": 0.8105 },"size": { "length": 0.031,"width": 0.062,"height": 0.121 },"orientation": { "z": 0.382683,"w": 0.92388 },"color": { "r": 1 } }, { "id": "objectRed2","type": "BOX","pos": { "x": 0.25,"y": -0.2,"z": 0.8105 },"size": { "length": 0.031,"width": 0.062,"height": 0.121 },"orientation": { "w": 1 },"color": { "r": 1 } }, { "id": "objectRed3","type": "BOX","pos": { "x": -0.4,"z": 0.819 },"size": { "length": 0.031,"width": 0.031,"height": 0.138 },"orientation": { "z": 0.382683,"w": 0.92388 },"color": { "r": 1 } }, diff --git a/main.py b/main.py index d8c59fa3de6fe516b342f8550c2d876034a1a1a4..0a4b69a5df2aefc7b3553efb853af501bf388000 100644 --- a/main.py +++ b/main.py @@ -29,6 +29,9 @@ max_topic = utils.MaxTopicLength() # buffer for mqtt log message_queue = queue.Queue() +# remember how often clear button was pressed (to only trigger clearing once) +last_clear_n_clicks = 0 + # button-id: (topic, payload) commands = { 'send-place-a-model': ('place-a/model', '1'), @@ -56,6 +59,20 @@ complex_commands = { ('place-b/reachability/arm2', 'place-b-reachability-2-json', cgv_connector_pb2.Reachability()), } + +def format_scene(scene: cgv_connector_pb2.Scene): + result = "" + for obj in scene.objects: + if obj.type == cgv_connector_pb2.Object.Type.BOX: + pos = obj.pos + result += f"\n<obj {obj.id:15} at ({pos.x:6.2} {pos.y:6.2} {pos.z:6.2})>" + return result + +conversion_topics = { + 'place-a/scene/update': (cgv_connector_pb2.Scene(), format_scene), + 'place-b/scene/update': (cgv_connector_pb2.Scene(), format_scene), +} + bytes_topics = [ 'place-a/scene/update', 'place-b/scene/update', @@ -111,7 +128,7 @@ app.layout = html.Div([ ], className="six columns"), ], className='row', style={'marginTop': '15px'}), ], className="six columns"), - ], className='row'), + ], className='row', style={'display': 'none'}), # dcc.Markdown("---"), html.Div([ # Row for commands html.Div([ # Column for commands of place a @@ -138,7 +155,7 @@ app.layout = html.Div([ id='mqtt-log', value="", readOnly=True, - style={**textarea_style_normal, 'fontFamily': 'Consolas, monospace'} + style={**textarea_style_normal, 'height': '400px', 'fontFamily': 'Consolas, monospace'} ), dcc.Checklist( id="should-scroll-mqtt-log", @@ -146,6 +163,7 @@ app.layout = html.Div([ value=["Auto-Scroll"], labelStyle={"display": "inline-block"}, ), + html.Button('Clear log', id='clear-mqtt-log', style=button_style_normal), dcc.Markdown("---"), html.Div([ html.P("Topic"), @@ -261,17 +279,23 @@ def send_complex(*_): Output('mqtt-log', 'value'), Output('javascriptLog', 'run'), Input('every-1-second', 'n_intervals'), + Input('clear-mqtt-log', 'n_clicks'), State('mqtt-log', 'value'), State('should-scroll-mqtt-log', 'value') ) -def append_to_mqtt_log(_n_intervals, value, should_scroll): +def append_to_mqtt_log(_n_intervals, clear_n_clicks, value, should_scroll): """ Periodically update mqtt log :param _n_intervals: Unused value of intervals + :param clear_n_clicks: clear.n_clicks :param value: current content of mqtt log :param should_scroll: checkbox value whether to scroll to the end after update :return: new content of mqtt log """ + global last_clear_n_clicks + if clear_n_clicks and clear_n_clicks > last_clear_n_clicks: + value = "" + last_clear_n_clicks = clear_n_clicks local_messages = [] while not message_queue.empty(): local_messages.append(message_queue.get_nowait()) @@ -349,7 +373,14 @@ def on_mqtt_connect(_client, _userdata, _flags, _rc, _properties=None): def on_mqtt_message(_client, _userdata, message): # Callback for mqtt client when message was received max_mqtt_topic_length = max_topic.process_topic(message.topic) - if message.topic in bytes_topics: + if message.topic in conversion_topics: + try: + obj, conversion = conversion_topics[message.topic] + obj.ParseFromString(message.payload) + payload = conversion(obj) + except Exception as e: + payload = f"(failed to parse {e})" + elif message.topic in bytes_topics: payload = "(ignored bytes)" else: try: diff --git a/run-protobuf.sh b/run-protobuf.sh new file mode 100755 index 0000000000000000000000000000000000000000..3d95f7e77c0e410017ed5373cf4ad5c9abf4acd4 --- /dev/null +++ b/run-protobuf.sh @@ -0,0 +1 @@ +protoc -I=. --python_out=. ./cgv_connector.proto