Skip to content

Instantly share code, notes, and snippets.

@ewpratten
Last active December 22, 2023 06:21
Show Gist options
  • Save ewpratten/0d8f7c7371380c9ca8adcfc6502ccf84 to your computer and use it in GitHub Desktop.
Save ewpratten/0d8f7c7371380c9ca8adcfc6502ccf84 to your computer and use it in GitHub Desktop.
.MM file parser
<map version="0.9.0">
<node TEXT="HATCHfield" FOLDED="false" POSITION="right" ID="5d2cd7ba58fb9567105aa56c" X_COGGLE_POSX="0" X_COGGLE_POSY="0">
<edge COLOR="#b4b4b4"/>
<font NAME="Helvetica" SIZE="17"/>
<node TEXT="Programming" FOLDED="false" POSITION="right" ID="ccc3ffd394e1d4a643ad61be">
<edge COLOR="#7aa3e5"/>
<font NAME="Helvetica" SIZE="15"/>
<node TEXT="Robot" FOLDED="false" POSITION="right" ID="a31a9d83733f857586f3dc13">
<edge COLOR="#83abe8"/>
<font NAME="Helvetica" SIZE="13"/>
<node TEXT="Autonomous" FOLDED="false" POSITION="right" ID="d50d359d144e9bf9e2d16bb6">
<edge COLOR="#87b0ea"/>
<font NAME="Helvetica" SIZE="12"/>
</node>
<node TEXT="Commands" FOLDED="false" POSITION="right" ID="f2d76085d6e358d5cdacb7bd">
<edge COLOR="#7ca8e7"/>
<font NAME="Helvetica" SIZE="12"/>
<node TEXT="ActionControl" FOLDED="false" POSITION="right" ID="71a14929fa26ceb0dfe7e8bd">
<edge COLOR="#77a6e4"/>
<font NAME="Helvetica" SIZE="12"/>
</node>
<node TEXT="DriveControl" FOLDED="false" POSITION="right" ID="e25a6a15fc263b2e04952e75">
<edge COLOR="#84aee7"/>
<font NAME="Helvetica" SIZE="12"/>
<node TEXT="Data manipulation" FOLDED="false" POSITION="right" ID="a1da0bd0f4554cc679651feb">
<edge COLOR="#7baae6"/>
<font NAME="Helvetica" SIZE="12"/>
<node TEXT="Deadbands" FOLDED="false" POSITION="right" ID="1236de0f2406c7466f2751ca">
<edge COLOR="#7bace6"/>
<font NAME="Helvetica" SIZE="12"/>
<node TEXT="Rotation" FOLDED="false" POSITION="right" ID="374fa21544774bd6277994de">
<edge COLOR="#82b3e8"/>
<font NAME="Helvetica" SIZE="12"/>
<node TEXT="Cubic scaling" FOLDED="false" POSITION="right" ID="914c2b8413270947cda08348">
<edge COLOR="#7cb1e6"/>
<font NAME="Helvetica" SIZE="12"/>
<node TEXT="weight: 20%" FOLDED="false" POSITION="right" ID="a1f37be7103e8a832d84e46a">
<edge COLOR="#70ade6"/>
<font NAME="Helvetica" SIZE="12"/>
</node>
</node>
<node TEXT="Limits" FOLDED="false" POSITION="right" ID="5710d71d601a5a6698af79ac">
<edge COLOR="#8ab9e8"/>
<font NAME="Helvetica" SIZE="12"/>
<node TEXT="Lower: 20%" FOLDED="false" POSITION="right" ID="867cb64d5e7353906779f555">
<edge COLOR="#84b7e6"/>
<font NAME="Helvetica" SIZE="12"/>
</node>
<node TEXT="Higher: 0%" FOLDED="false" POSITION="right" ID="eec9c601d586883e507b9547">
<edge COLOR="#8bbae7"/>
<font NAME="Helvetica" SIZE="12"/>
</node>
</node>
</node>
<node TEXT="Speed" FOLDED="false" POSITION="right" ID="6c989a5a81db29286525b638">
<edge COLOR="#7eafe5"/>
<font NAME="Helvetica" SIZE="12"/>
<node TEXT="No limits" FOLDED="false" POSITION="right" ID="8345dd633030d050d76ad5d7">
<edge COLOR="#7db0e4"/>
<font NAME="Helvetica" SIZE="12"/>
</node>
<node TEXT="Cubic scaling" FOLDED="false" POSITION="right" ID="3be85b86ef290a3efceb97d7">
<edge COLOR="#88b6e5"/>
<font NAME="Helvetica" SIZE="12"/>
<node TEXT="weight: 10%" FOLDED="false" POSITION="right" ID="7e91e158fd413f4764c34573">
<edge COLOR="#7cb2e5"/>
<font NAME="Helvetica" SIZE="12"/>
</node>
</node>
</node>
</node>
</node>
<node TEXT="Outputs " FOLDED="false" POSITION="right" ID="0e9b9367a53b54972bfaf1c6">
<edge COLOR="#89b3e8"/>
<font NAME="Helvetica" SIZE="12"/>
<node TEXT="DriveTrain" FOLDED="false" POSITION="right" ID="31bd44e29c8c2bc95f1c363c">
<edge COLOR="#89b4e6"/>
<font NAME="Helvetica" SIZE="12"/>
<node TEXT="RaiderDrive" FOLDED="false" POSITION="right" ID="0e5444657705c97318334f75">
<edge COLOR="#8bb7e6"/>
<font NAME="Helvetica" SIZE="12"/>
<node TEXT="Speed" FOLDED="false" POSITION="right" ID="e416d4bdfff56eee0c0d7a00">
<edge COLOR="#84b5e5"/>
<font NAME="Helvetica" SIZE="12"/>
</node>
<node TEXT="Rotation" FOLDED="false" POSITION="right" ID="64a7f3ebd92f53fa54f9d467">
<edge COLOR="#83b3e2"/>
<font NAME="Helvetica" SIZE="12"/>
</node>
</node>
</node>
</node>
<node TEXT="Turn joystick data into movement instructions" FOLDED="false" POSITION="right" ID="675760f71fe75c32de2f2719">
<edge COLOR="#8cb5e9"/>
<font NAME="Helvetica" SIZE="12"/>
</node>
<node TEXT="Inputs" FOLDED="false" POSITION="right" ID="8a3de9fe7918bc6de801fa2f">
<edge COLOR="#8cb4e7"/>
<font NAME="Helvetica" SIZE="12"/>
<node TEXT="Driver Controller" FOLDED="false" POSITION="right" ID="345a9959dfb517fb5545e8af">
<edge COLOR="#8db6e6"/>
<font NAME="Helvetica" SIZE="12"/>
<node TEXT="Left joystick" FOLDED="false" POSITION="right" ID="7c5d1b3a2c23dc36fe6f4c94">
<edge COLOR="#94bce7"/>
<font NAME="Helvetica" SIZE="12"/>
<node TEXT="Rotation of robot" FOLDED="false" POSITION="right" ID="a699b90f2323a76ff6f5f8d7">
<edge COLOR="#9dc2e8"/>
<font NAME="Helvetica" SIZE="12"/>
</node>
</node>
<node TEXT="Triggers" FOLDED="false" POSITION="right" ID="f5ba35902a4a43d4bc102241">
<edge COLOR="#8cb6e5"/>
<font NAME="Helvetica" SIZE="12"/>
<node TEXT="Speed of robot" FOLDED="false" POSITION="right" ID="ccaa81de834cee9de6f020f8">
<edge COLOR="#88b5e5"/>
<font NAME="Helvetica" SIZE="12"/>
</node>
</node>
<node TEXT="X button" FOLDED="false" POSITION="right" ID="e72e8f2beaa525e98979a28e">
<edge COLOR="#90b9e7"/>
<font NAME="Helvetica" SIZE="12"/>
<node TEXT="Flip robot heading" FOLDED="false" POSITION="right" ID="8a2eda5fae756e80da39c253">
<edge COLOR="#89b6e6"/>
<font NAME="Helvetica" SIZE="12"/>
</node>
</node>
</node>
</node>
</node>
<node TEXT="IntakeControl" FOLDED="false" POSITION="right" ID="6d7a7939cf4d39f4b108b902">
<edge COLOR="#84afe9"/>
<font NAME="Helvetica" SIZE="12"/>
</node>
</node>
<node TEXT="Subsystems" FOLDED="false" POSITION="right" ID="c58888c4d47a0c3954dccf7d">
<edge COLOR="#8bb2ea"/>
<font NAME="Helvetica" SIZE="12"/>
<node TEXT="Lighting" FOLDED="false" POSITION="right" ID="ebcda7ed093d622697bca041">
<edge COLOR="#94baed"/>
<font NAME="Helvetica" SIZE="12"/>
</node>
<node TEXT="Climber" FOLDED="false" POSITION="right" ID="c9d5ab2ad9a5b672ad040510">
<edge COLOR="#8ab4eb"/>
<font NAME="Helvetica" SIZE="12"/>
</node>
<node TEXT="Intake" FOLDED="false" POSITION="right" ID="07fdc234702cf5eda0fa41fb">
<edge COLOR="#85afe8"/>
<font NAME="Helvetica" SIZE="12"/>
</node>
<node TEXT="Flap" FOLDED="false" POSITION="right" ID="4f4866f0fbd9dc03ff6523c8">
<edge COLOR="#80ade9"/>
<font NAME="Helvetica" SIZE="12"/>
</node>
<node TEXT="Pneumatics" FOLDED="false" POSITION="right" ID="271d6aefb5449cc91b2ac456">
<edge COLOR="#96baeb"/>
<font NAME="Helvetica" SIZE="12"/>
</node>
<node TEXT="DriveTrain" FOLDED="false" POSITION="right" ID="3c877ef139ae7e88fe02ef3f">
<edge COLOR="#8bb3e8"/>
<font NAME="Helvetica" SIZE="12"/>
<node TEXT="Methods" FOLDED="false" POSITION="right" ID="d149457e9a28eff02d753597">
<edge COLOR="#86b1e7"/>
<font NAME="Helvetica" SIZE="12"/>
<node TEXT="RaiderDrive" FOLDED="false" POSITION="right" ID="743a2076906a53e48e3d8bf5">
<edge COLOR="#87b4e8"/>
<font NAME="Helvetica" SIZE="12"/>
<node TEXT="Outputs" FOLDED="false" POSITION="right" ID="808b3eff1d8ef6a22635e148">
<edge COLOR="#7db0e8"/>
<font NAME="Helvetica" SIZE="12"/>
<node TEXT="Direct signals to left and right gearboxes" FOLDED="false" POSITION="right" ID="761c3458fe2c5d297a12756a">
<edge COLOR="#7ab0e7"/>
<font NAME="Helvetica" SIZE="12"/>
</node>
</node>
<node TEXT="Passes movement data through a slew limiter" FOLDED="false" POSITION="right" ID="811e40caceafc9d8e3b702d3">
<edge COLOR="#82b3e7"/>
<font NAME="Helvetica" SIZE="12"/>
</node>
<node TEXT="Inputs" FOLDED="false" POSITION="right" ID="f267ebcad69f108bad27114f">
<edge COLOR="#8bb9ea"/>
<font NAME="Helvetica" SIZE="12"/>
<node TEXT="Speed" FOLDED="false" POSITION="right" ID="b603185ef602a0f0284863e4">
<edge COLOR="#91bdea"/>
<font NAME="Helvetica" SIZE="12"/>
</node>
<node TEXT="Rotation" FOLDED="false" POSITION="right" ID="bc448007fccbaf043c89a7bb">
<edge COLOR="#88b9e9"/>
<font NAME="Helvetica" SIZE="12"/>
</node>
</node>
</node>
<node TEXT="RaiderDrive" FOLDED="false" POSITION="right" ID="7c90d929c0b6ecadbc038df4">
<edge COLOR="#87b4e8"/>
<font NAME="Helvetica" SIZE="12"/>
<node TEXT="Outputs" FOLDED="false" POSITION="right" ID="4ec6d55ec71f2959ea8c4b76">
<edge COLOR="#7db0e8"/>
<font NAME="Helvetica" SIZE="12"/>
<node TEXT="Direct signals to left and right gearboxes" FOLDED="false" POSITION="right" ID="fe6e2e972f14d2e67b2e5a82">
<edge COLOR="#7ab0e7"/>
<font NAME="Helvetica" SIZE="12"/>
</node>
</node>
<node TEXT="Inputs" FOLDED="false" POSITION="right" ID="5000a291b575f6efc0bc3929">
<edge COLOR="#8bb9ea"/>
<font NAME="Helvetica" SIZE="12"/>
<node TEXT="Speed" FOLDED="false" POSITION="right" ID="cbe767818d51aec76e1ffed3">
<edge COLOR="#91bdea"/>
<font NAME="Helvetica" SIZE="12"/>
</node>
<node TEXT="Rotation" FOLDED="false" POSITION="right" ID="4bf566292c517372a0b420e9">
<edge COLOR="#88b9e9"/>
<font NAME="Helvetica" SIZE="12"/>
</node>
</node>
</node>
</node>
</node>
</node>
</node>
<node TEXT="Vision" FOLDED="false" POSITION="right" ID="9aa32e4b05d784e23fa9b49e">
<edge COLOR="#7ea8e7"/>
<font NAME="Helvetica" SIZE="13"/>
</node>
</node>
</node>
</map>
[{"name": "HATCHfield", "children": [{"name": "Programming", "children": [{"name": "Robot", "children": [{"name": "Autonomous", "type": "leaf"}, {"name": "Commands", "children": [{"name": "ActionControl", "type": "leaf"}, {"name": "DriveControl", "children": [{"name": "Data manipulation", "children": [{"name": "Deadbands", "children": [{"name": "Rotation", "children": [{"name": "Cubic scaling", "children": [{"name": "weight: 20%", "type": "leaf"}], "type": "branch"}, {"name": "Limits", "children": [{"name": "Lower: 20%", "type": "leaf"}, {"name": "Higher: 0%", "type": "leaf"}], "type": "branch"}], "type": "branch"}, {"name": "Speed", "children": [{"name": "No limits", "type": "leaf"}, {"name": "Cubic scaling", "children": [{"name": "weight: 10%", "type": "leaf"}], "type": "branch"}], "type": "branch"}], "type": "branch"}], "type": "branch"}, {"name": "Outputs ", "children": [{"name": "DriveTrain", "children": [{"name": "RaiderDrive", "children": [{"name": "Speed", "type": "leaf"}, {"name": "Rotation", "type": "leaf"}], "type": "branch"}], "type": "branch"}], "type": "branch"}, {"name": "Turn joystick data into movement instructions", "type": "leaf"}, {"name": "Inputs", "children": [{"name": "Driver Controller", "children": [{"name": "Left joystick", "children": [{"name": "Rotation of robot", "type": "leaf"}], "type": "branch"}, {"name": "Triggers", "children": [{"name": "Speed of robot", "type": "leaf"}], "type": "branch"}, {"name": "X button", "children": [{"name": "Flip robot heading", "type": "leaf"}], "type": "branch"}], "type": "branch"}], "type": "branch"}], "type": "branch"}, {"name": "IntakeControl", "type": "leaf"}], "type": "branch"}, {"name": "Subsystems", "children": [{"name": "Lighting", "type": "leaf"}, {"name": "Climber", "type": "leaf"}, {"name": "Intake", "type": "leaf"}, {"name": "Flap", "type": "leaf"}, {"name": "Pneumatics", "type": "leaf"}, {"name": "DriveTrain", "children": [{"name": "Methods", "children": [{"name": "RaiderDrive", "children": [{"name": "Outputs", "children": [{"name": "Direct signals to left and right gearboxes", "type": "leaf"}], "type": "branch"}, {"name": "Passes movement data through a slew limiter", "type": "leaf"}, {"name": "Inputs", "children": [{"name": "Speed", "type": "leaf"}, {"name": "Rotation", "type": "leaf"}], "type": "branch"}], "type": "branch"}, {"name": "RaiderDrive", "children": [{"name": "Outputs", "children": [{"name": "Direct signals to left and right gearboxes", "type": "leaf"}], "type": "branch"}, {"name": "Inputs", "children": [{"name": "Speed", "type": "leaf"}, {"name": "Rotation", "type": "leaf"}], "type": "branch"}], "type": "branch"}], "type": "branch"}], "type": "branch"}], "type": "branch"}], "type": "branch"}, {"name": "Vision", "type": "leaf"}], "type": "branch"}], "type": "branch"}]
import json
import argparse
import xml.etree.ElementTree as ET
ap = argparse.ArgumentParser()
ap.add_argument("file")
args = ap.parse_args()
debug = False
raw_mm = ""
try:
with open(args.file, "r") as fp:
raw_mm = fp.read()
fp.close()
except:
print("File IO Error")
exit(1)
## Parse file
xml = ET.fromstring(raw_mm)
def xmlToDict(xml):
output = []
for elem in list(xml):
# Check for non-node
if "TEXT" not in elem.attrib:
continue
# Create a json element
name = elem.attrib['TEXT']
json_element = {"name": name}
# Try to recurse
try:
if debug:
print(f"Branching from: {name}")
json_element["children"] = xmlToDict(elem)
except Exception as e:
if debug:
print(f"Hit end of branch: {name}")
continue
# Detect node type
if json_element["children"]:
json_element["type"] = "branch"
else:
json_element["type"] = "leaf"
del json_element["children"]
output.append(json_element)
return output
mind_map = xmlToDict(xml)
## Convert format
# Write to file
json.dump(mind_map, open(args.file + ".json", "w"))
## Pprint
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment