diff --git a/examples/bike/main.py b/examples/bike/main.py index d8eaf99..aa1fb4c 100644 --- a/examples/bike/main.py +++ b/examples/bike/main.py @@ -1,8 +1,5 @@ -import matplotlib.pyplot as plt -import networkx as nx - import onshape_api as osa -from onshape_api.graph import create_graph, get_urdf_components, show_graph +from onshape_api.graph import create_graph, get_urdf_components from onshape_api.models.robot import Robot from onshape_api.parse import ( get_instances, @@ -41,5 +38,5 @@ links, joints = get_urdf_components(graph, doc.wid, parts, mass_properties, mates, client) -robot = Robot(name="my_robot", links=links, joints=joints) +robot = Robot(name="bike", links=links, joints=joints) robot.save("bike.urdf") diff --git a/onshape_api/graph.py b/onshape_api/graph.py index b16b380..06ff2d6 100644 --- a/onshape_api/graph.py +++ b/onshape_api/graph.py @@ -1,5 +1,6 @@ import io -from typing import Union +import random +from typing import Optional, Union import matplotlib.pyplot as plt import networkx as nx @@ -34,16 +35,28 @@ from onshape_api.utilities.mesh import transform_mesh +def generate_names(max_length: int) -> list[str]: + with open("/Users/holycow/Projects/onshape-api/onshape_api/words.txt") as file: + words = file.read().splitlines() + + if max_length > len(words): + raise ValueError("max_length exceeds the number of available words") + + return random.sample(words, max_length) + + def show_graph(graph: nx.Graph): nx.draw_circular(graph, with_labels=True) plt.show() + def convert_to_digraph(graph: nx.Graph) -> nx.DiGraph: _centrality = nx.closeness_centrality(graph) _root_node = max(_centrality, key=_centrality.get) _graph = nx.bfs_tree(graph, _root_node) return _graph, _root_node + def create_graph( occurences: dict[str, Occurrence], instances: dict[str, Instance], @@ -75,20 +88,26 @@ def create_graph( return graph + def flip_tuple(t: tuple) -> tuple: return t[::-1] -def download_stl_mesh(did, wid, eid, partID, client: Client, path: str): + +def download_stl_mesh(did, wid, eid, partID, client: Client, transform: np.ndarray = None, path: Optional[str] = None): + if transform is None: + transform = np.eye(4) + buffer = io.BytesIO() client.download_stl(did, wid, eid, partID, buffer) buffer.seek(0) raw_mesh = stl.mesh.Mesh.from_file(None, fh=buffer) - transformed_mesh = transform_mesh(raw_mesh, np.eye(4)) + transformed_mesh = transform_mesh(raw_mesh, transform) transformed_mesh.save(path) return path + def get_urdf_components( graph: Union[nx.Graph, nx.DiGraph], workspaceId: str, @@ -106,6 +125,9 @@ def get_urdf_components( _child_transforms = {} _sorted_nodes = list(nx.topological_sort(graph)) + _names = generate_names(len(_sorted_nodes)) + _names_to_node_mapping = dict(zip(_sorted_nodes, _names)) + for node in _sorted_nodes: for edge in graph.edges(node): # check if the mate is between root assembly and subassembly @@ -119,21 +141,22 @@ def get_urdf_components( _child_transforms[node] = mates[_mate_key].matedEntities[0].matedCS.part_to_mate_transform joints.append( RevoluteJoint( - name=f"joint_{edge[0]}_{edge[1]}", - parent=edge[0], - child=edge[1], + name=f"joint_{_names_to_node_mapping[edge[0]]}_{_names_to_node_mapping[edge[1]]}", + parent=_names_to_node_mapping[edge[0]], + child=_names_to_node_mapping[edge[1]], origin=Origin.from_matrix(mates[_mate_key].matedEntities[1].matedCS.part_to_mate_transform), limits=JointLimits(effort=1.0, velocity=1.0, lower=-1.0, upper=1.0), - axis=Axis((1, 0, 0)), - )) + axis=Axis((0, 1, 0)), + ) + ) elif mates[_mate_key].mateType == MATETYPE.FASTENED: _child_transforms[node] = mates[_mate_key].matedEntities[0].matedCS.part_to_mate_transform joints.append( FixedJoint( - name=f"joint_{edge[0]}_{edge[1]}", - parent=edge[0], - child=edge[1], + name=f"joint_{_names_to_node_mapping[edge[0]]}_{_names_to_node_mapping[edge[1]]}", + parent=_names_to_node_mapping[edge[0]], + child=_names_to_node_mapping[edge[1]], origin=Origin.from_matrix(mates[_mate_key].matedEntities[1].matedCS.part_to_mate_transform), ) ) @@ -161,16 +184,16 @@ def get_urdf_components( parts[node].elementId, parts[node].partId, client, - f"{node}.stl" + f"{_names_to_node_mapping[node]}.stl", ) links.append( Link( - name=node, + name=_names_to_node_mapping[node], visual=VisualLink( origin=_default_origin, geometry=MeshGeometry(stl_path), - material=Material.from_color(name=f"{node}_material", color=COLORS.RED) + material=Material.from_color(name=f"{_names_to_node_mapping[node]}_material", color=COLORS.RED), ), inertial=InertialLink( origin=Origin(_center_of_mass, _default_principal_axes), @@ -182,15 +205,9 @@ def get_urdf_components( ixy=_inertia_matrix[0, 1], ixz=_inertia_matrix[0, 2], iyz=_inertia_matrix[1, 2], - ) + ), ), - collision=CollisionLink( - origin=_default_origin, - geometry=MeshGeometry(stl_path) - ) + collision=CollisionLink(origin=_default_origin, geometry=MeshGeometry(stl_path)), ) ) - - return links, joints - diff --git a/onshape_api/words.txt b/onshape_api/words.txt new file mode 100644 index 0000000..efbaa28 --- /dev/null +++ b/onshape_api/words.txt @@ -0,0 +1,721 @@ +abomasnow +abra +absol +accelgor +aegislash +aerodactyl +aggron +aipom +alakazam +alomomola +altaria +amaura +ambipom +amoonguss +ampharos +anorith +arbok +arcanine +arceus +archen +archeops +ariados +armaldo +aromatisse +aron +articuno +audino +aurorus +avalugg +axew +azelf +azumarill +azurill +bagon +baltoy +banette +barbaracle +barboach +basculin +bastiodon +bayleef +beartic +beautifly +beedrill +beheeyem +beldum +bellossom +bellsprout +bergmite +bibarel +bidoof +binacle +bisharp +blastoise +blaziken +blissey +blitzle +boldore +bonsly +bouffalant +braixen +braviary +breloom +bronzong +bronzor +budew +buizel +bulbasaur +buneary +bunnelby +burmy +butterfree +cacnea +cacturne +camerupt +carbink +carnivine +carracosta +carvanha +cascoon +castform +caterpie +celebi +chandelure +chansey +charizard +charmander +charmeleon +chatot +cherrim +cherubi +chesnaught +chespin +chikorita +chimchar +chimecho +chinchou +chingling +cinccino +clamperl +clauncher +clawitzer +claydol +clefable +clefairy +cleffa +cloyster +cobalion +cofagrigus +combee +combusken +conkeldurr +corphish +corsola +cottonee +cradily +cranidos +crawdaunt +cresselia +croagunk +crobat +croconaw +crustle +cryogonal +cubchoo +cubone +cyndaquil +darkrai +darmanitan +darumaka +dedenne +deerling +deino +delcatty +delibird +delphox +deoxys +dewgong +dewott +dialga +diancie +diggersby +diglett +ditto +dodrio +doduo +donphan +doublade +dragalge +dragonair +dragonite +drapion +dratini +drifblim +drifloon +drilbur +drowzee +druddigon +ducklett +dugtrio +dunsparce +duosion +durant +dusclops +dusknoir +duskull +dustox +dwebble +eelektrik +eelektross +eevee +ekans +electabuzz +electivire +electrike +electrode +elekid +elgyem +emboar +emolga +empoleon +entei +escavalier +espeon +espurr +excadrill +exeggcute +exeggutor +exploud +farfetch'd +fearow +feebas +fennekin +feraligatr +ferroseed +ferrothorn +finneon +flaaffy +flabébé +flareon +fletchinder +fletchling +floatzel +floette +florges +flygon +foongus +forretress +fraxure +frillish +froakie +frogadier +froslass +furfrou +furret +gabite +gallade +galvantula +garbodor +garchomp +gardevoir +gastly +gastrodon +genesect +gengar +geodude +gible +gigalith +girafarig +giratina +glaceon +glalie +glameow +gligar +gliscor +gloom +gogoat +golbat +goldeen +golduck +golem +golett +golurk +goodra +goomy +gorebyss +gothita +gothitelle +gothorita +gourgeist +granbull +graveler +greninja +grimer +grotle +groudon +grovyle +growlithe +grumpig +gulpin +gurdurr +gyarados +happiny +hariyama +haunter +hawlucha +haxorus +heatmor +heatran +heliolisk +helioptile +heracross +herdier +hippopotas +hippowdon +hitmonchan +hitmonlee +hitmontop +honchkrow +honedge +ho-oh +hoopa +hoothoot +hoppip +horsea +houndoom +houndour +huntail +hydreigon +hypno +igglybuff +illumise +infernape +inkay +ivysaur +jellicent +jigglypuff +jirachi +jolteon +joltik +jumpluff +jynx +kabuto +kabutops +kadabra +kakuna +kangaskhan +karrablast +kecleon +keldeo +kingdra +kingler +kirlia +klang +klefki +klink +klinklang +koffing +krabby +kricketot +kricketune +krokorok +krookodile +kyogre +kyurem +lairon +lampent +landorus +lanturn +lapras +larvesta +larvitar +latias +latios +leafeon +leavanny +ledian +ledyba +lickilicky +lickitung +liepard +lileep +lilligant +lillipup +linoone +litleo +litwick +lombre +lopunny +lotad +loudred +lucario +ludicolo +lugia +lumineon +lunatone +luvdisc +luxio +luxray +machamp +machoke +machop +magby +magcargo +magikarp +magmar +magmortar +magnemite +magneton +magnezone +makuhita +malamar +mamoswine +manaphy +mandibuzz +manectric +mankey +mantine +mantyke +maractus +mareep +marill +marowak +marshtomp +masquerain +mawile +medicham +meditite +meganium +meloetta +meowstic +meowth +mesprit +metagross +metang +metapod +mew +mewtwo +mienfoo +mienshao +mightyena +milotic +miltank +mime jr. +minccino +minun +misdreavus +mismagius +moltres +monferno +mothim +mr. mime +mudkip +muk +munchlax +munna +murkrow +musharna +natu +nidoking +nidoqueen +nidoran +nidoran♂ +nidorina +nidorino +nincada +ninetales +ninjask +noctowl +noibat +noivern +nosepass +numel +nuzleaf +octillery +oddish +omanyte +omastar +onix +oshawott +pachirisu +palkia +palpitoad +pancham +pangoro +panpour +pansage +pansear +paras +parasect +patrat +pawniard +pelipper +persian +petilil +phanpy +phantump +phione +pichu +pidgeot +pidgeotto +pidgey +pidove +pignite +pikachu +piloswine +pineco +pinsir +piplup +plusle +politoed +poliwag +poliwhirl +poliwrath +ponyta +poochyena +porygon +porygon2 +porygon-z +primeape +prinplup +probopass +psyduck +pumpkaboo +pupitar +purrloin +purugly +pyroar +quagsire +quilava +quilladin +qwilfish +raichu +raikou +ralts +rampardos +rapidash +raticate +rattata +rayquaza +regice +regigigas +regirock +registeel +relicanth +remoraid +reshiram +reuniclus +rhydon +rhyhorn +rhyperior +riolu +roggenrola +roselia +roserade +rotom +rufflet +sableye +salamence +samurott +sandile +sandshrew +sandslash +sawk +sawsbuck +scatterbug +sceptile +scizor +scolipede +scrafty +scraggy +scyther +seadra +seaking +sealeo +seedot +seel +seismitoad +sentret +serperior +servine +seviper +sewaddle +sharpedo +shaymin +shedinja +shelgon +shellder +shellos +shelmet +shieldon +shiftry +shinx +shroomish +shuckle +shuppet +sigilyph +silcoon +simipour +simisage +simisear +skarmory +skiddo +skiploom +skitty +skorupi +skrelp +skuntank +slaking +slakoth +sliggoo +slowbro +slowking +slowpoke +slugma +slurpuff +smeargle +smoochum +sneasel +snivy +snorlax +snorunt +snover +snubbull +solosis +solrock +spearow +spewpa +spheal +spinarak +spinda +spiritomb +spoink +spritzee +squirtle +stantler +staraptor +staravia +starly +starmie +staryu +steelix +stoutland +stunfisk +stunky +sudowoodo +suicune +sunflora +sunkern +surskit +swablu +swadloon +swalot +swampert +swanna +swellow +swinub +swirlix +swoobat +sylveon +taillow +talonflame +tangela +tangrowth +tauros +teddiursa +tentacool +tentacruel +tepig +terrakion +throh +thundurus +timburr +tirtouga +togekiss +togepi +togetic +torchic +torkoal +tornadus +torterra +totodile +toxicroak +tranquill +trapinch +treecko +trevenant +tropius +trubbish +turtwig +tympole +tynamo +typhlosion +tyranitar +tyrantrum +tyrogue +tyrunt +umbreon +unfezant +unown +ursaring +uxie +vanillish +vanillite +vanilluxe +vaporeon +venipede +venomoth +venonat +venusaur +vespiquen +vibrava +victini +victreebel +vigoroth +vileplume +virizion +vivillon +volbeat +volcanion +volcarona +voltorb +vullaby +vulpix +wailmer +wailord +walrein +wartortle +watchog +weavile +weedle +weepinbell +weezing +whimsicott +whirlipede +whiscash +whismur +wigglytuff +wingull +wobbuffet +woobat +wooper +wormadam +wurmple +wynaut +xatu +xerneas +yamask +yanma +yanmega +yveltal +zangoose +zapdos +zebstrika +zekrom +zigzagoon +zoroark +zorua +zubat +zweilous +zygarde