diff --git a/lecture_03/202_visualize_model_with_meshes_artist.py b/lecture_03/202_visualize_model_with_meshes_artist.py index e4d4de4..908bd02 100644 --- a/lecture_03/202_visualize_model_with_meshes_artist.py +++ b/lecture_03/202_visualize_model_with_meshes_artist.py @@ -2,7 +2,7 @@ from compas.robots import LocalPackageMeshLoader from compas.robots import RobotModel -model = RobotModel.from_urdf_file("models/05_origins_meshes.urdf") +model = RobotModel.from_urdf_file("models/04_visual_origins.urdf") loader = LocalPackageMeshLoader("models", "basic") model.load_geometry(loader) diff --git a/lecture_03/207_robot_artist_grasshopper.ghx b/lecture_03/207_robot_artist_grasshopper.ghx index 7c212e6..51b6bc6 100644 --- a/lecture_03/207_robot_artist_grasshopper.ghx +++ b/lecture_03/207_robot_artist_grasshopper.ghx @@ -48,10 +48,10 @@ - 43 - 220 + -381 + -28 - 0.85 + 0.579042733 @@ -73,8 +73,8 @@ - GhPython, Version=7.27.23032.13001, Culture=neutral, PublicKeyToken=null - 7.27.23032.13001 + GhPython, Version=7.22.22255.5001, Culture=neutral, PublicKeyToken=null + 7.22.22255.5001 00000000-0000-0000-0000-000000000000 @@ -85,9 +85,9 @@ - 19 + 25 - + c552a431-af5b-46a9-a8a4-0fcbc27ef596 @@ -197,7 +197,7 @@ 360 -360 0 - 0 + -3 @@ -242,7 +242,7 @@ 360 -360 0 - 0 + -48 @@ -287,7 +287,7 @@ 360 -360 0 - 0 + 11 @@ -332,7 +332,7 @@ 360 -360 0 - 0 + 173 @@ -377,7 +377,7 @@ 360 -360 0 - 0 + 23 @@ -422,7 +422,7 @@ 360 -360 0 - 0 + 28 @@ -613,16 +613,16 @@ 61.74512 - 1158.706 - 65.79695 + 1158.707 + 65.79697 - 1158.185 - 94.11979 + 1158.186 + 94.11981 937.925 - 90.06796 + 90.06797 A quick note Calibri @@ -639,8 +639,8 @@ 932.925 56.74512 - 230.7811 - 42.37467 + 230.7819 + 42.37469 938.4459 @@ -971,9 +971,9 @@ 566 - 245 + 251 66 - 39 + 28 598 @@ -996,13 +996,13 @@ 568 - 247 + 253 15 - 35 + 24 577 - 264.5 + 265 @@ -1022,13 +1022,13 @@ 613 - 247 + 253 17 - 35 + 24 621.5 - 264.5 + 265 @@ -1084,8 +1084,8 @@ robot.artist = Artist(model) 151 - 966 - 738 + 2518 + 1829 true true @@ -1101,9 +1101,9 @@ robot.artist = Artist(model) 79 - 110 + 124 68 - 56 + 28 93 @@ -1132,9 +1132,9 @@ robot.artist = Artist(model) 108 - 112 + 126 37 - 52 + 24 126.5 @@ -1158,7 +1158,7 @@ robot.artist = Artist(model) - + """ Visualizes the robot. @@ -1284,11 +1284,19 @@ class RobotVisualize(component): Visualizes the robot. COMPAS FAB v0.27.0 + + 927 + 298 + + + 1944 + 1777 + true true 2 - iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAACxIAAAsSAdLdfvwAAAHYSURBVEhLtZSxSgNBEIZVCEFQTDoRi4BgLcQHCGJpkSaVja2dnYUglqlEbcQulUUqHyGFpYUvEMgTBDs7z/87do7ZvVUixIPvbndm55/Z2btbKYriX8kal0nW+Bd2b19b4oJnzl8z/BUJv4hCfIh+6o8mVCFGYiII7Hm/R74zMROI2xOI7di6NAhnGtATiN04vJ8xhXWExb/XEoQFpVM8iuswvxPWhhxRWzQ/ENXOUwcBz4IkD2FOAtrmRT1RGzWv2gPcKoOcCBNkT+gLkrB9gwM1f9kOPWkT7cM2M01uVQVysAvrIyL0PqoorKOdiFkhtNAfeNQin8AO1A7NKqolCetZ5w+c9dH3wC3toW+PMfFrPPJRCIVli6gZwuI0AUSFLErWKLHcW1MenK6BYACXFqOrLebBPq7sNvBIjG37N8W4wZ8VihMPKrsNUhBLxIGkLQkMnVib9c429zqRaIrE/BtijCTSDWJQVqvLdjX0GpFgisR+PHAJTYPgk/AJj71GJAgK5qvNiUZsnZyXgmvrG1+Nnb37ID5N9aIJKNi+5F/ZvhqXCWC10fwM46g9EE1AwQslgOb+YZUk0E31ogkokF+F/dR+ZfPo1M4B3lItqBmWTda4PIqVb4c7lSMXBSLEAAAAAElFTkSuQmCC + iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAALEQAACxEBf2RfkQAAAdhJREFUSEu1lLFKA0EQhlUIQVBMOhGLgGAtxAcIYmmRJpWNrZ2dhSCWqURtxC6VRSofIYWlhS8QyBMEOzvP/zt2jtm9VSLEg+9ud2bnn9nZu1spiuJfyRqXSdb4F3ZvX1vigmfOXzP8FQm/iEJ8iH7qjyZUIUZiIgjseb9HvjMxE4jbE4jt2Lo0CGca0BOI3Ti8nzGFdYTFv9cShAWlUzyK6zC/E9aGHFFbND8Q1c5TBwHPgiQPYU4C2uZFPVEbNa/aA9wqg5wIE2RP6AuSsH2DAzV/2Q49aRPtwzYzTW5VBXKwC+sjIvQ+qiiso52IWSG00B941CKfwA7UDs0qqiUJ61nnD5z10ffALe2hb48x8Ws88lEIhWWLqBnC4jQBRIUsStYosdxbUx6croFgAJcWo6st5sE+ruw28EiMbfs3xbjBnxWKEw8quw1SEEvEgaQtCQydWJv1zjb3OpFoisT8G2KMJNINYlBWq8t2NfQakWCKxH48cAlNg+CT8AmPvUYkCArmq82JRmydnJeCa+sbX42dvfsgPk31ogko2L7kX9m+GpcJYLXR/AzjqD0QTUDBCyWA5v5hlSTQTfWiCSiQX4X91H5l8+jUzgHeUi2oGZZN1rg8ipVvhzuVIxcFIsQAAAAASUVORK5CYII= false 98063dc0-ab65-47c6-b8d7-e393c79c73ed @@ -1890,7 +1898,7 @@ COMPAS FAB v0.27.0 true 2 - iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAACxIAAAsSAdLdfvwAAAEhSURBVEhLtZVrscJAFIOxgAUsYAELWLgWsIAFLGABC1jAAhbK+diGpp38oezNTIYlnc3JPk67GYbhXxnFnoxiT2Zxjm3xVHwWeQgfozZD9IrihF0RMxkveS8S4I3oFcUJGMjsWjwW/8ax9EvxjegVxQaMZIKhg9S+Zfti9opig6c8IBjYfz2D52L2imKDEvLrUHrfPsbZK4rtcGeTDUrPqvwCZK8otsmaeEMYofTSvMAuekVxXuBzSwqM0XQmXQto23xFXQrIUOkpJKwu4IdMAf337QLeC9krig2aTEr1hKfnwNHg19cUeKPBZXrv9FWN5gbQ0wNvtFWvCuAmpOTwKcy5SP+sLHpFcQKp/aYsSYCfXtdC3w9OT0axJ6PYj8PmBbHgR+CZxxdVAAAAAElFTkSuQmCC + iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAALEQAACxEBf2RfkQAAASFJREFUSEu1lWuxwkAUg7GABSxgAQtYuBawgAUsYAELWMACFsr52Iamnfyh7M1MhiWdzck+TrsZhuFfGcWejGJPZnGObfFUfBZ5CB+jNkP0iuKEXREzGS95LxLgjegVxQkYyOxaPBb/xrH0S/GN6BXFBoxkgqGD1L5l+2L2imKDpzwgGNh/PYPnYvaKYoMS8utQet8+xtkriu1wZ5MNSs+q/AJkryi2yZp4Qxih9NK8wC56RXFe4HNLCozRdCZdC2jbfEVdCshQ6SkkrC7gh0wB/fftAt4L2SuKDZpMSvWEp+fA0eDX1xR4o8Fleu/0VY3mBtDTA2+0Va8K4Cak5PApzLlI/6wsekVxAqn9pixJgJ9e10LfD05PRrEno9iPw+YFseBH4JnHF1UAAAAASUVORK5CYII= false a497134c-5233-4faa-ad82-48f5328e51d7 @@ -2025,7 +2033,7 @@ COMPAS FAB v0.27.0 - + config = zero_config.copy() config.joint_values = joints @@ -2038,6 +2046,7 @@ config.joint_values = joints 558 571 + true true true false @@ -2052,9 +2061,9 @@ config.joint_values = joints 694 - 223 + 230 137 - 57 + 44 774 @@ -2090,13 +2099,13 @@ config.joint_values = joints 696 - 225 + 232 63 - 26 + 20 729 - 238.25 + 242 @@ -2122,13 +2131,13 @@ config.joint_values = joints 696 - 251 + 252 63 - 27 + 20 729 - 264.75 + 262 @@ -2148,13 +2157,591 @@ config.joint_values = joints 789 - 225 + 232 40 - 53 + 40 809 - 251.5 + 252 + + + + + + + + + + + + + + 59e0b89a-e487-49f8-bab8-b5bab16be14c + Panel + + + + + A panel for custom notes and text values + e4a46439-38b4-48c4-8796-ec69238d99fe + Panel + + false + 0 + d0e86e28-9389-480a-bdc5-584b1a08a56f + 1 + Double click to edit panel content… + + + + + + 795 + 99 + 339 + 116 + + 0 + 0 + 0 + + 795.311 + 99.07526 + + + + + + + 255;255;250;90 + + true + true + true + false + false + true + + + + + + + + + 410755b1-224a-4c1e-a407-bf32fb45ea7e + 00000000-0000-0000-0000-000000000000 + GhPython Script + + + + + frame = robot.model.forward_kinematics(config) +print frame + +solutions = list(robot.iter_inverse_kinematics(frame, config)) +print(len(solutions)) + +for cfg in solutions: + print(cfg) + + GhPython provides a Python script component + + 366 + 366 + + + 1477 + 1357 + + true + false + false + 490717e7-80a9-4adf-b23b-b06fe3711a84 + false + true + GhPython Script + Python + + + + + + 1155 + 453 + 125 + 64 + + + 1209 + 485 + + + + + + 2 + 84fa917c-1ed8-4db3-8be1-7bdc4a6495a2 + 84fa917c-1ed8-4db3-8be1-7bdc4a6495a2 + 3 + 3ede854e-c753-40eb-84cb-b48008f14fd4 + 8ec86459-bf01-4409-baee-174d0d2b13d0 + 8ec86459-bf01-4409-baee-174d0d2b13d0 + + + + + true + Script variable Python + dbcc7168-15a3-4495-b344-868a99a51d4b + robot + robot + true + 0 + true + 1c75c63f-3ba0-40c4-9f8e-319bd52ecccf + 1 + 87f87f55-5b71-41f4-8aea-21d494016f81 + + + + + + 1157 + 455 + 37 + 30 + + + 1177 + 470 + + + + + + + + true + Script input config. + cd98d929-f414-4f64-862d-4bcdc19c8e39 + config + config + true + 0 + true + d0e86e28-9389-480a-bdc5-584b1a08a56f + 1 + 87f87f55-5b71-41f4-8aea-21d494016f81 + + + + + + 1157 + 485 + 37 + 30 + + + 1177 + 500 + + + + + + + + The execution information, as output and error streams + 64144802-6f76-4796-b798-32e143c3a78e + out + out + false + 0 + + + + + + 1224 + 455 + 54 + 20 + + + 1251 + 465 + + + + + + + + Script output frame. + 0fc3a626-b2a3-4532-871c-47cd0448e820 + frame + frame + false + 0 + + + + + + 1224 + 475 + 54 + 20 + + + 1251 + 485 + + + + + + + + Script output solutions. + 84f59616-1a11-4533-bcbc-2d20ab7019c9 + a + solutions + false + 0 + + + + + + 1224 + 495 + 54 + 20 + + + 1251 + 505 + + + + + + + + + + + + + + 410755b1-224a-4c1e-a407-bf32fb45ea7e + 00000000-0000-0000-0000-000000000000 + Draw + + + + + """ +Draws COMPAS geometry in Grasshopper. +""" +from ghpythonlib.componentbase import executingcomponent as component + +from compas.artists import Artist + + +class CompasToRhinoGeometry(component): + def RunScript(self, cg): + if not cg: + return None + + return Artist(cg).draw() + + Draws COMPAS geometry in Grasshopper. + true + true + 2 + + iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAACxEAAAsRAX9kX5EAAAQOSURBVEhLtZVvTJVlGMbfAeIhwQMBdjgICXSCyCHUGk2SVaNVUosP0fQDRkYblast0rEWmyvHzFhstlYsBw2TD2UTCtbMdKvVmJ3oz1q2ecr5J2MRLDsI4cG8uq7nnOftqAfrS8/2O8/7vs957+v+8zz363AkxUglV5EMkkmyyTJyDckhubFnWltK0shisogkAXASoZFCPGQJuZr4yHJSQq4nN5BSEog9KyT5RKISk9CCIhrywkvk4bWkjNzrzcwOc0busvyIL69wnNf95DFSScqJxPxE78pG8kICCldpuI5UkP7UVA9qau/HnsEQXtixF+s2bEZRyUr9G+kZmReyc3xn0zO8Y7yXiNKo1CqKy0Q0FOoKUk+vpz1pS7D+4S145fUDhue37UHP7iAOHo4YunsOobi0xoiRlUTpTCeqYUIB5bMsKTkFgdJKvPn2mDE09PGEERhgFFasuXU7cgtuRdkdvVagiqgmqoUELquDhjxQatC4KYi7G7uw5q4WVNx0Jza0dBjDErtlTRN8gXUort6OirUjVkD1UN1sHRIKFJBVBI9ujbisbT6ApvYJNDyyF/6i1RcCt71qDF8iYCO4ooAiSChgr4sqmo1RKyD0/9h7clAb5d9T1NAaTCigtYXgCT3LWYdzQQEVWbvBpESGRfU9XW6atNYbo9/jYCDLwROZrsgzJIvooOrAKlUGK5BHdLhcj+MjUFRaizf+Tp5rfB9RiuypVi2ULs1eK6CDojaQUEBoLd74e8UOnvK7Im1ETuqwqs0I3futgPqPthoClU2obdhlvL5UIN74ULmDkZsdtAVckWeHh4cbf5+eDYXnzs/TsB1cihZIii8uTsv4dmlWwWxyigfJi9LgW1GLqts7jBGbc3ku4/trHBysc9C+Kvq8r68Ps/N/YfTUDN74chLdoxOugLqhcqbQFIk6p4q+kQx5s5b/wtkYIe9rlucy/sl9Dj5/0EF9SXR908gpbBw8gS0fncbRqTlXQE1KIiqObdfaWepPaoABbsUZzu1EzW0zMZ7LeMfqqPHqJ3dg/bvHDP3fTMq4Bpe4d4m+Cdpa6orabopIW08t3BbPFI7o3BgR63lV60t4YCDksmvst5j9fwREMpGQIrJfN4lpFhLVF82vgirnvMZDz3Wj7q0fLmL/j2fw6fFwVEA/MSUrFI8V1CwxReWfDM+Eps+dR9uHxzE+HcHRyT/x+AfHUN3znZm1Vtd35GKBRHBYIUWnKHSY8qdmIvODR6ZQvvNrw2uHxxGmUc1f/DxtZj03NuINXomYgFJUyHu07Auh4OWgy407v0Lv2K84HT6HrYdOmnvznn7+CxxKUU5nZ2cN71G/+3t4t426FHYFcfLMHJ4e+QmfnfjDCJn39PP/AedvQrmhHRUNKOEAAAAASUVORK5CYII= + + false + f8b7864c-b28e-4af1-a21c-d8a36a29110c + true + true + Draw + Draw + + + + + + 1385 + 455 + 73 + 28 + + + 1421 + 469 + + + + + + 1 + 84fa917c-1ed8-4db3-8be1-7bdc4a6495a2 + 1 + 8ec86459-bf01-4409-baee-174d0d2b13d0 + + + + + true + The COMPAS geometry or datastructure to be drawn. + 334407d1-03e7-42b3-9ace-e874abc67381 + cg + cg + true + 0 + true + 0fc3a626-b2a3-4532-871c-47cd0448e820 + 1 + 87f87f55-5b71-41f4-8aea-21d494016f81 + + + + + + 1387 + 457 + 19 + 24 + + + 1398 + 469 + + + + + + + + The Rhino geometry object. + d6f77e63-e4ed-4914-9c00-a30daaff5b6c + rg + rg + false + 0 + + + + + + 1436 + 457 + 20 + 24 + + + 1446 + 469 + + + + + + + + + + + + + + 59daf374-bc21-4a5e-8282-5504fb7ae9ae + List Item + + + + + 0 + Retrieve a specific item from a list. + b4722bed-48f2-4ce4-b0f4-9e38a03dd730 + List Item + Item + + + + + + 1390 + 511 + 64 + 64 + + + 1424 + 543 + + + + + + 3 + 8ec86459-bf01-4409-baee-174d0d2b13d0 + 2e3ab970-8545-46bb-836c-1c11e5610bce + cb95db89-6165-43b6-9c41-5702bc5bf137 + 1 + 8ec86459-bf01-4409-baee-174d0d2b13d0 + + + + + 1 + Base list + 862c1ac6-dee6-4f25-81c2-b0a1ab658d8c + List + L + false + 84f59616-1a11-4533-bcbc-2d20ab7019c9 + 1 + + + + + + 1392 + 513 + 17 + 20 + + + 1402 + 523 + + + + + + + + Item index + a342454b-c01f-4fcc-8dc5-849adfebd452 + Index + i + false + d2b066cf-6a79-486b-bcae-e73c8d64b2a5 + 1 + + + + + + 1392 + 533 + 17 + 20 + + + 1402 + 543 + + + + + + 1 + + + + + 1 + {0} + + + + + 0 + + + + + + + + + + + Wrap index to list bounds + 56e6b446-4fe1-4459-a7ec-1249e812cd28 + Wrap + W + false + 0 + + + + + + 1392 + 553 + 17 + 20 + + + 1402 + 563 + + + + + + 1 + + + + + 1 + {0} + + + + + true + + + + + + + + + + + Item at {i'} + 827b925c-9cb2-4a58-9a8c-03f057aa0e85 + false + Item + i + false + 0 + + + + + + 1439 + 513 + 13 + 60 + + + 1445.5 + 543 @@ -2166,6 +2753,104 @@ config.joint_values = joints + + + 57da07bd-ecab-415d-9d86-af36d7073abc + Number Slider + + + + + Numeric slider for single values + d2b066cf-6a79-486b-bcae-e73c8d64b2a5 + Number Slider + + false + 0 + + + + + + 1201 + 533 + 160 + 20 + + + 1201.317 + 533.0587 + + + + + + 3 + 1 + 1 + 10 + 0 + 0 + 2 + + + + + + + + + 59e0b89a-e487-49f8-bab8-b5bab16be14c + Panel + + + + + A panel for custom notes and text values + db1c7e6a-e3be-4371-9f47-f07a46b74961 + Panel + + false + 0 + 84f59616-1a11-4533-bcbc-2d20ab7019c9 + 1 + Double click to edit panel content… + + + + + + 1478 + 418 + 600 + 175 + + 0 + 0 + 0 + + 1478.196 + 418.3023 + + + + + + + 255;255;250;90 + + true + true + true + false + false + true + + + + + + @@ -2173,7 +2858,7 @@ config.joint_values = joints - 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 diff --git a/lecture_03/210_build_your_own_robot.py b/lecture_03/210_build_your_own_robot.py index 7e68314..f52d8b7 100644 --- a/lecture_03/210_build_your_own_robot.py +++ b/lecture_03/210_build_your_own_robot.py @@ -9,7 +9,7 @@ from compas.robots import Joint from compas.robots import RobotModel -# create cylinder in yz plane +# create cylinder in yz plane (we will use this for everything) radius, length = 0.3, 5 cylinder = Cylinder(Circle(Plane([0, 0, 0], [1, 0, 0]), radius), length) cylinder.transform(Translation.from_vector([length / 2.0, 0, 0])) @@ -22,26 +22,34 @@ mesh2 = Mesh.from_shape(cylinder) # add links -link0 = model.add_link("world") +link0 = model.add_link("world") #this one doesn't have geometry link1 = model.add_link("link1", visual_mesh=mesh1, visual_color=(0.2, 0.5, 0.6)) link2 = model.add_link("link2", visual_mesh=mesh2, visual_color=(0.5, 0.6, 0.2)) -# add joints between the links +# add joints between the links where it moves (link0 child, link1 parent) axis = (0, 0, 1) -origin = Frame.worldXY() -model.add_joint("joint1", Joint.CONTINUOUS, link0, link1, origin, axis) +origin1 = Frame.worldXY() +model.add_joint("joint1", Joint.CONTINUOUS, link0, link1, origin1, axis) -origin = Frame((length, 0, 0), (1, 0, 0), (0, 1, 0)) -model.add_joint("joint2", Joint.CONTINUOUS, link1, link2, origin, axis) +origin2 = Frame((length, 0, 0), (1, 0, 0), (0, 1, 0)) +model.add_joint("joint2", Joint.CONTINUOUS, link1, link2, origin2, axis) # Create a configuration object matching the number of joints in your model -# configuration = .... +configuration = model.zero_configuration() #close to all zeros +configuration.joint_values =[2, 1.57] # Update the model using the artist artist = Artist(model) -# artist.update ... +artist.update(configuration) # Render everything artist.draw_visual() artist.redraw() + + +artist1 = Artist(frame) +artist2 = Artist(model) +artist2.update(config) + +a = [artist.draw()] \ No newline at end of file diff --git a/lecture_03/assignment_02/02-assignment.gh b/lecture_03/assignment_02/02-assignment.gh new file mode 100644 index 0000000..e979311 Binary files /dev/null and b/lecture_03/assignment_02/02-assignment.gh differ diff --git a/lecture_03/assignment_02/hanging man_SCKA.gif b/lecture_03/assignment_02/hanging man_SCKA.gif new file mode 100644 index 0000000..10e6463 Binary files /dev/null and b/lecture_03/assignment_02/hanging man_SCKA.gif differ diff --git a/lecture_03/assignment_02/hanging_man.jpg b/lecture_03/assignment_02/hanging_man.jpg new file mode 100644 index 0000000..103f2a7 Binary files /dev/null and b/lecture_03/assignment_02/hanging_man.jpg differ diff --git a/lecture_04/306_robot_from_ros_artist.py b/lecture_04/306_robot_from_ros_artist.py index f7795ae..1746ba5 100644 --- a/lecture_04/306_robot_from_ros_artist.py +++ b/lecture_04/306_robot_from_ros_artist.py @@ -1,4 +1,4 @@ -z # Before running this example, make sure to run +# Before running this example, make sure to run # "docker compose up" on the docker/gofa-noetic folder from compas.artists import Artist from compas_fab.backends import RosClient diff --git a/lecture_04/assignment_03/assignment_03.ghx b/lecture_04/assignment_03/assignment_03.ghx new file mode 100644 index 0000000..caf4712 --- /dev/null +++ b/lecture_04/assignment_03/assignment_03.ghx @@ -0,0 +1,5751 @@ + + + + + + + + 0 + 2 + 2 + + + + + + + 1 + 0 + 7 + + + + + + c4f913db-409d-41a9-88e1-f6f90989047d + Shaded + 1 + + 100;150;0;0 + + + 100;0;150;0 + + + + + + 637527254194888879 + + assignment_03.ghx + + + + + 0 + + + + + + 1395 + 84 + + 1.80625045 + + + + + 0 + + + + + + + 0 + + + + + 1 + + + + + GhPython, Version=7.22.22255.5001, Culture=neutral, PublicKeyToken=null + 7.22.22255.5001 + + 00000000-0000-0000-0000-000000000000 + + + + + + + + + 61 + + + + + c552a431-af5b-46a9-a8a4-0fcbc27ef596 + Group + + + + + 1 + + 150;170;135;255 + + A group of Grasshopper objects + bfe572e7-d997-4c3c-8488-4e03d01804ea + b278407c-79b3-49ef-a2c8-ee682b33d9ef + 6fe2e9d2-130c-4a02-b347-a1c6b831fc5a + 9a4be73c-3082-4c74-be27-41c7c1688c53 + 4 + 3dd78fb5-3c65-4715-b2db-b9489d44fd71 + Group + + + + + + + + + + + c552a431-af5b-46a9-a8a4-0fcbc27ef596 + Group + + + + + 1 + + 150;170;135;255 + + A group of Grasshopper objects + d5ffda3e-a3ab-4688-9de8-1d9d9e2789e3 + 4b0a07e0-a378-4f92-8f0a-6c1f1fb427f2 + 1d31a79f-b7ba-423f-944c-23f606999dae + eaec99d4-5f03-4209-953f-02aee1235de3 + 4a5bf47a-b0af-4831-a451-6b776364bb7e + 5 + 5a4ca04f-0f26-4978-bcce-92edaa3c4b8e + Group + + + + + + + + + + + c552a431-af5b-46a9-a8a4-0fcbc27ef596 + Group + + + + + 1 + + 150;170;135;255 + + A group of Grasshopper objects + 781a5de8-c54c-4805-927f-519a45da032f + 4b0a07e0-a378-4f92-8f0a-6c1f1fb427f2 + 1d31a79f-b7ba-423f-944c-23f606999dae + eaec99d4-5f03-4209-953f-02aee1235de3 + 4a5bf47a-b0af-4831-a451-6b776364bb7e + 20c7f0ab-fd13-4bd7-a130-c6fe893d2a0b + 47c152bc-c823-4835-aad3-3bf5c281e892 + d19cf29a-0512-4632-b4e0-ecc00c5b8487 + 2ceac33a-a5ff-4a42-8067-32e6a2c7fbee + ac227038-eb23-4cb5-94d8-f63bb92375a4 + b3787c61-219b-4ed9-b49f-1e7dd56236b1 + b395bfb0-5717-46c4-924c-a3ba167b1e0d + 4e66fe1b-29b3-4955-9524-ca986decd9ac + 78471367-17af-4599-8661-808ba87f82a6 + bfa816f1-e4c0-482e-9515-4b540fd2f427 + 82091d9c-f1c0-4207-8d3d-b1dca673d5df + 16 + 8b8d6fbf-db19-4267-9188-c4fdd76620b6 + Group + + + + + + + + + + + 8ec86459-bf01-4409-baee-174d0d2b13d0 + Data + + + + + Contains a collection of generic data + 4e66fe1b-29b3-4955-9524-ca986decd9ac + Data + Robot + false + aa5456e2-dffb-4ba4-82cb-38af4281a720 + 1 + + + + + + 1254 + 168 + 50 + 24 + + + 1279.353 + 180.9772 + + + + + + + + + + 7f5c6c55-f846-4a08-9c9a-cfdc285cc6fe + Scribble + + + + + false + + 46.70692 + 119.7138 + + + 272.0458 + 119.7138 + + + 272.0458 + 139.8124 + + + 46.70692 + 139.8124 + + A quick note + Cambria + 82091d9c-f1c0-4207-8d3d-b1dca673d5df + false + Scribble + Scribble + 22 + 1) Load robot from ROS + + + + + + 41.70692 + 114.7138 + 235.3389 + 30.09864 + + + 46.70692 + 119.7138 + + + + + + + + + + 8ec86459-bf01-4409-baee-174d0d2b13d0 + Data + + + + + Contains a collection of generic data + aacb02be-ffde-4997-b910-3a5670a6e5b1 + Data + Target planes + false + 33d8782b-58a4-4217-9659-139215119c80 + 1 + + + + + + 1259 + 496 + 50 + 24 + + + 1284.441 + 508.6404 + + + + + + + + + + c552a431-af5b-46a9-a8a4-0fcbc27ef596 + Group + + + + + 1 + + 150;240;218;146 + + A group of Grasshopper objects + 0c3c0677-cbf3-46be-b539-e48399697bc7 + de6b7a53-8f17-48cc-bb14-1aedc473dd1c + 04770360-9eb5-44e4-911f-142deec44bdc + aacb02be-ffde-4997-b910-3a5670a6e5b1 + 50ee1702-2c6a-4092-b68b-7fd9ec30c129 + 9dbe68e7-ae2d-4df4-89a9-ae0ec5759854 + d17c9d6f-7bf6-411c-816c-4c1caad151b9 + 7 + cf91e427-c398-45be-b915-f55275cc67b7 + Group + + + + + + + + + + + 8ec86459-bf01-4409-baee-174d0d2b13d0 + Data + + + + + Contains a collection of generic data + d385349b-7e03-4362-b9d0-eacd34e2562b + Data + Pickup plane + false + bc441cf5-1159-4fe7-b3bc-3b1cac9ac3f4 + 1 + + + + + + 1241 + 348 + 50 + 24 + + + 1266.929 + 360.6916 + + + + + + + + + + c552a431-af5b-46a9-a8a4-0fcbc27ef596 + Group + + + + + 1 + + 150;240;218;146 + + A group of Grasshopper objects + d385349b-7e03-4362-b9d0-eacd34e2562b + 66c3b06d-1415-476b-875b-53498de1860a + c9e84bc7-5f07-46ef-9e42-32f7d85d0c13 + 39a429c7-2480-4ff8-8f4c-5bd8a47369a7 + 224add91-1cc7-47af-8c77-af2d42147144 + ff0bbdd7-eb5b-4ed6-a652-505db2c0ac8c + 6 + 3c032157-3bf9-40ee-9b12-e4e807d15ccc + Group + + + + + + + + + + + 7f5c6c55-f846-4a08-9c9a-cfdc285cc6fe + Scribble + + + + + false + + 46.70692 + 281.4785 + + + 269.3387 + 281.4785 + + + 269.3387 + 301.5771 + + + 46.70692 + 301.5771 + + A quick note + Cambria + ff0bbdd7-eb5b-4ed6-a652-505db2c0ac8c + false + Scribble + Scribble + 22 + 2) Define pick-up plane + + + + + + 41.70692 + 276.4785 + 232.6318 + 30.09863 + + + 46.70692 + 281.4785 + + + + + + + + + + 7f5c6c55-f846-4a08-9c9a-cfdc285cc6fe + Scribble + + + + + false + + 62.70692 + 465.9947 + + + 279.9891 + 465.9947 + + + 279.9891 + 486.2222 + + + 62.70692 + 486.2222 + + A quick note + Cambria + 9dbe68e7-ae2d-4df4-89a9-ae0ec5759854 + false + Scribble + Scribble + 22 + 3) Define target planes + + + + + + 57.70692 + 460.9947 + 227.2822 + 30.22754 + + + 62.70692 + 465.9947 + + + + + + + + + + 410755b1-224a-4c1e-a407-bf32fb45ea7e + 00000000-0000-0000-0000-000000000000 + Robot Visualize + + + + + """ +Visualizes the robot. + +COMPAS FAB v0.27.0 +""" +from compas.artists import Artist +from compas.geometry import Frame +from compas.geometry import Transformation +from compas_fab.robots import PlanningScene +from ghpythonlib.componentbase import executingcomponent as component + + +class RobotVisualize(component): + def RunScript( + self, + robot, + group, + configuration, + show_visual, + show_collision, + show_frames, + show_base_frame, + show_end_effector_frame, + show_cm, + show_acm, + ): + + visual = None + collision = None + collision_meshes = None + attached_meshes = None + frames = None + base_frame = None + ee_frame = None + + if robot: + show_visual = True if show_visual is None else show_visual + show_cm = True if show_cm is None else show_cm + show_acm = True if show_acm is None else show_acm + configuration = configuration or robot.zero_configuration() + + robot.update(configuration, visual=show_visual, collision=show_collision) + compas_frames = robot.transformed_frames(configuration, group) + + if show_visual: + visual = robot.artist.draw_visual() + + if show_collision: + collision = robot.artist.draw_collision() + + if show_base_frame: + base_compas_frame = compas_frames[0] + artist = Artist(base_compas_frame) + base_frame = artist.draw() + + if show_end_effector_frame: + ee_compas_frame = robot.forward_kinematics( + configuration, group, options=dict(solver="model") + ) + artist = Artist(ee_compas_frame) + ee_frame = artist.draw() + + if show_frames: + frames = [] + for compas_frame in compas_frames[1:]: + artist = Artist(compas_frame) + frame = artist.draw() + frames.append(frame) + + if show_cm or show_acm: + scene = PlanningScene(robot) + scene = robot.client.get_planning_scene() + + collision_meshes = [] + attached_meshes = [] + + if show_cm: + for co in scene.world.collision_objects: + header = co.header + frame_id = header.frame_id + cms = co.to_collision_meshes() + + for cm in cms: + if cm.frame != Frame.worldXY(): + t = Transformation.from_frame(cm.frame) + mesh = cm.mesh.transformed(t) + else: + mesh = cm.mesh + + collision_meshes.append(Artist(mesh).draw()) + + if show_acm: + for aco in scene.robot_state.attached_collision_objects: + for acm in aco.to_attached_collision_meshes(): + frame_id = aco.object["header"]["frame_id"] + frame = robot.forward_kinematics( + configuration, options=dict(link=frame_id) + ) + t = Transformation.from_frame(frame) + + # Local CM frame + if ( + acm.collision_mesh.frame + and acm.collision_mesh.frame != Frame.worldXY() + ): + t = t * Transformation.from_frame( + acm.collision_mesh.frame + ) + + mesh = acm.collision_mesh.mesh.transformed(t) + + attached_meshes.append(Artist(mesh).draw()) + + return ( + visual, + collision, + collision_meshes, + attached_meshes, + frames, + base_frame, + ee_frame, + ) + + Visualizes the robot. +COMPAS FAB v0.27.0 + true + true + 2 + + iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAALEQAACxEBf2RfkQAAAdhJREFUSEu1lLFKA0EQhlUIQVBMOhGLgGAtxAcIYmmRJpWNrZ2dhSCWqURtxC6VRSofIYWlhS8QyBMEOzvP/zt2jtm9VSLEg+9ud2bnn9nZu1spiuJfyRqXSdb4F3ZvX1vigmfOXzP8FQm/iEJ8iH7qjyZUIUZiIgjseb9HvjMxE4jbE4jt2Lo0CGca0BOI3Ti8nzGFdYTFv9cShAWlUzyK6zC/E9aGHFFbND8Q1c5TBwHPgiQPYU4C2uZFPVEbNa/aA9wqg5wIE2RP6AuSsH2DAzV/2Q49aRPtwzYzTW5VBXKwC+sjIvQ+qiiso52IWSG00B941CKfwA7UDs0qqiUJ61nnD5z10ffALe2hb48x8Ws88lEIhWWLqBnC4jQBRIUsStYosdxbUx6croFgAJcWo6st5sE+ruw28EiMbfs3xbjBnxWKEw8quw1SEEvEgaQtCQydWJv1zjb3OpFoisT8G2KMJNINYlBWq8t2NfQakWCKxH48cAlNg+CT8AmPvUYkCArmq82JRmydnJeCa+sbX42dvfsgPk31ogko2L7kX9m+GpcJYLXR/AzjqD0QTUDBCyWA5v5hlSTQTfWiCSiQX4X91H5l8+jUzgHeUi2oGZZN1rg8ipVvhzuVIxcFIsQAAAAASUVORK5CYII= + + false + 7a58f25a-3dc8-4dfa-bf0f-35404273569e + true + true + Robot Visualize + Robot Visualize + + + + + + 2354 + 140 + 257 + 204 + + + 2501 + 242 + + + + + + 10 + 84fa917c-1ed8-4db3-8be1-7bdc4a6495a2 + 84fa917c-1ed8-4db3-8be1-7bdc4a6495a2 + 84fa917c-1ed8-4db3-8be1-7bdc4a6495a2 + 84fa917c-1ed8-4db3-8be1-7bdc4a6495a2 + 84fa917c-1ed8-4db3-8be1-7bdc4a6495a2 + 84fa917c-1ed8-4db3-8be1-7bdc4a6495a2 + 84fa917c-1ed8-4db3-8be1-7bdc4a6495a2 + 84fa917c-1ed8-4db3-8be1-7bdc4a6495a2 + 84fa917c-1ed8-4db3-8be1-7bdc4a6495a2 + 84fa917c-1ed8-4db3-8be1-7bdc4a6495a2 + 7 + 8ec86459-bf01-4409-baee-174d0d2b13d0 + 8ec86459-bf01-4409-baee-174d0d2b13d0 + 8ec86459-bf01-4409-baee-174d0d2b13d0 + 8ec86459-bf01-4409-baee-174d0d2b13d0 + 8ec86459-bf01-4409-baee-174d0d2b13d0 + 8ec86459-bf01-4409-baee-174d0d2b13d0 + 8ec86459-bf01-4409-baee-174d0d2b13d0 + + + + + true + The robot. + 439bbb30-bb2a-4f39-bfd6-8205cd93fd09 + robot + robot + true + 0 + true + 619d4216-bdfd-4395-b679-83b02e397c53 + 1 + 87f87f55-5b71-41f4-8aea-21d494016f81 + 2 + + + + + + 2356 + 142 + 130 + 20 + + + 2422.5 + 152 + + + + + + + + true + The planning group used for end-effector and base visualization. + ad36f822-0439-4ba3-b51a-c348f6f591ec + group + group + true + 0 + true + 0 + 37261734-eec7-4f50-b6a8-b8d1f3c4396b + + + + + + 2356 + 162 + 130 + 20 + + + 2422.5 + 172 + + + + + + + + true + The robot's full configuration. + 9fb95b19-f673-4906-9998-b63a5811ea88 + configuration + configuration + true + 0 + true + 4ca3f55b-10fb-41c3-9f24-2b4809b96eeb + 1 + 87f87f55-5b71-41f4-8aea-21d494016f81 + + + + + + 2356 + 182 + 130 + 20 + + + 2422.5 + 192 + + + + + + + + true + Whether or not to show the robot's visual meshes. + 22d8ace2-7a15-4a22-9430-2f721280765e + show_visual + show_visual + true + 0 + true + 0 + d60527f5-b5af-4ef6-8970-5f96fe412559 + + + + + + 2356 + 202 + 130 + 20 + + + 2422.5 + 212 + + + + + + + + true + Whether or not to show the robot's collision meshes. + ad827435-eaa9-47db-8456-0f04c22dde3a + show_collision + show_collision + true + 0 + true + 0 + d60527f5-b5af-4ef6-8970-5f96fe412559 + + + + + + 2356 + 222 + 130 + 20 + + + 2422.5 + 232 + + + + + + + + true + Whether or not to show the robot's joint frames. + 35824dc3-741e-4a85-9d9f-f350f6328850 + show_frames + show_frames + true + 0 + true + 0 + d60527f5-b5af-4ef6-8970-5f96fe412559 + + + + + + 2356 + 242 + 130 + 20 + + + 2422.5 + 252 + + + + + + + + true + Whether or not to show the robot's base frame. + 5c36de85-2908-4ed4-8bfb-be05a5fc15a0 + show_base_frame + show_base_frame + true + 0 + true + 0 + d60527f5-b5af-4ef6-8970-5f96fe412559 + + + + + + 2356 + 262 + 130 + 20 + + + 2422.5 + 272 + + + + + + + + true + Whether or not to show the robot's end-effector frame. + 43679585-4dff-44fc-8144-04d51b6597a3 + show_end_effector_frame + show_end_effector_frame + true + 0 + true + 0 + d60527f5-b5af-4ef6-8970-5f96fe412559 + + + + + + 2356 + 282 + 130 + 20 + + + 2422.5 + 292 + + + + + + + + true + Whether or not to show the collision meshes (if any). + b0245b8b-4b25-480e-8434-34500dd361dd + show_cm + show_cm + true + 0 + true + 0 + d60527f5-b5af-4ef6-8970-5f96fe412559 + + + + + + 2356 + 302 + 130 + 20 + + + 2422.5 + 312 + + + + + + + + true + Whether or not to show the attached collision meshes (if any). + c258dd5f-afd6-4742-9840-e8ae6df45c59 + show_acm + show_acm + true + 0 + true + 0 + d60527f5-b5af-4ef6-8970-5f96fe412559 + + + + + + 2356 + 322 + 130 + 20 + + + 2422.5 + 332 + + + + + + + + Rhino meshes of the robot's visual geometry (if any). + b51fd205-41de-4772-b77b-54118aa40c2c + visual + visual + false + 0 + + + + + + 2516 + 142 + 93 + 28 + + + 2562.5 + 156.2857 + + + + + + + + Rhino meshes of the robot's collision geometry (if any). + 3fd4309e-805a-4b2a-8b39-fb39cda51d21 + collision + collision + false + 0 + + + + + + 2516 + 170 + 93 + 29 + + + 2562.5 + 184.8571 + + + + + + + + Rhino meshes of the scene's collision meshes (if any). + ba8f5aaf-7d4f-4021-b0f3-328651e5f766 + collision_meshes + collision_meshes + false + 0 + + + + + + 2516 + 199 + 93 + 28 + + + 2562.5 + 213.4286 + + + + + + + + Rhino meshes of the scene's attached collision meshes (if any). + 00b4652c-1968-4bef-b124-5b86f4dc25bc + attached_meshes + attached_meshes + false + 0 + + + + + + 2516 + 227 + 93 + 29 + + + 2562.5 + 242 + + + + + + + + The robot's joint frames as Rhino planes (if any). + 243eeb3c-e1ad-4233-9a1a-b0ec9fd1c962 + frames + frames + false + 0 + + + + + + 2516 + 256 + 93 + 28 + + + 2562.5 + 270.5714 + + + + + + + + The robot's base frame as a Rhino plane (if any). + 91fd1995-e0da-4f23-a4c6-afeefc044dee + base_frame + base_frame + false + 0 + + + + + + 2516 + 284 + 93 + 29 + + + 2562.5 + 299.1429 + + + + + + + + The robot's end-effector frame as a Rhino plane (if any). + 5a2c4711-ae2f-4f0f-b633-afc7c8fccfd2 + ee_frame + ee_frame + false + 0 + + + + + + 2516 + 313 + 93 + 29 + + + 2562.5 + 327.7143 + + + + + + + + + + + + + + 7f5c6c55-f846-4a08-9c9a-cfdc285cc6fe + Scribble + + + + + false + + 46.70691 + 651.1613 + + + 317.5712 + 651.1613 + + + 317.5712 + 671.2599 + + + 46.70691 + 671.2599 + + A quick note + Cambria + fccb98c9-c6e5-4caa-8384-ca0ddf85fd1f + false + Scribble + Scribble + 22 + 4) Solve IK for pick-up plane + + + + + + 41.70691 + 646.1613 + 280.8643 + 30.09863 + + + 46.70691 + 651.1613 + + + + + + + + + + 8ec86459-bf01-4409-baee-174d0d2b13d0 + Data + + + + + Contains a collection of generic data + 02bc89eb-6961-419b-a5c7-ecf1d7beb296 + Data + Pickup config + false + 4cba6477-f3c9-45a8-b24e-d6b1c262c1d6 + 1 + + + + + + 1243 + 708 + 50 + 24 + + + 1268.677 + 720.8832 + + + + + + + + + + 7f5c6c55-f846-4a08-9c9a-cfdc285cc6fe + Scribble + + + + + false + + 73.59003 + 675.2849 + + + 238.8635 + 675.2849 + + + 238.8635 + 689.9958 + + + 73.59003 + 689.9958 + + A quick note + Cambria + 6e5b9db8-970d-4e5b-bf3d-6ec1c492b072 + false + Scribble + Scribble + 16 + Results in pickup config + + + + + + 68.59003 + 670.2849 + 175.2734 + 24.71094 + + + 73.59003 + 675.2849 + + + + + + + + + + c552a431-af5b-46a9-a8a4-0fcbc27ef596 + Group + + + + + 1 + + 150;240;218;146 + + A group of Grasshopper objects + fccb98c9-c6e5-4caa-8384-ca0ddf85fd1f + 02bc89eb-6961-419b-a5c7-ecf1d7beb296 + 6e5b9db8-970d-4e5b-bf3d-6ec1c492b072 + fb4c5d39-e0a5-4c45-b606-72de43c589ac + b96209a7-93e4-4212-b096-c83e82b4da7b + 98209ace-c305-4683-b351-d9b9daf31e36 + d6aa3cd1-1856-4140-9204-fc16b23a82d0 + 7 + 3962a36b-d451-45d1-acb9-c99a5708db90 + Group + + + + + + + + + + + 00027467-0d24-4fa7-b178-8dc0ac5f42ec + Value List + + + + + Provides a list of preset values to choose from + 137a3255-a54e-4e4c-a9c3-e6d902b2a8bb + 2 + 3 + Value List + List + false + 0 + + + + + 0 + Pickup config + false + + + + + 1 + Trajectory + true + + + + + + 1589 + 172 + 227 + 22 + + + + + + + + + + eeafc956-268e-461d-8e73-ee05c6f72c01 + Stream Filter + + + + + Filters a collection of input streams + 471af287-d88e-43f4-9bb2-98daa088f633 + Stream Filter + Filter + + + + + + 2044 + 171 + 77 + 64 + + + 2076 + 203 + + + + + + 3 + 2e3ab970-8545-46bb-836c-1c11e5610bce + 8ec86459-bf01-4409-baee-174d0d2b13d0 + 8ec86459-bf01-4409-baee-174d0d2b13d0 + 1 + 8ec86459-bf01-4409-baee-174d0d2b13d0 + + + + + Index of Gate stream + fde7ac2c-1b3d-473c-8b2b-4addc4d52e1a + Gate + G + false + 137a3255-a54e-4e4c-a9c3-e6d902b2a8bb + 1 + + + + + + 2046 + 173 + 15 + 20 + + + 2055 + 183 + + + + + + 1 + + + + + 1 + {0} + + + + + 0 + + + + + + + + + + + 2 + Input stream at index 0 + e6a67ce5-d55f-4ec2-a44c-573291be81a5 + false + Stream 0 + 0 + true + a38644b3-ef3b-4bc2-bf1d-8843907a4a1f + 1 + + + + + + 2046 + 193 + 15 + 20 + + + 2055 + 203 + + + + + + + + 2 + Input stream at index 1 + 14985ec3-7977-426f-bc6b-ad27afc61e04 + false + Stream 1 + 1 + true + a4b043bc-8e30-4b4c-bb40-e7f42497696d + 1 + + + + + + 2046 + 213 + 15 + 20 + + + 2055 + 223 + + + + + + + + 2 + Filtered stream + ddfd1927-535b-4f08-acf1-f1762fa62a54 + false + Stream + S(1) + false + 0 + + + + + + 2091 + 173 + 28 + 60 + + + 2105 + 203 + + + + + + + + + + + + + + c552a431-af5b-46a9-a8a4-0fcbc27ef596 + Group + + + + + 1 + + 150;0;155;194 + + A group of Grasshopper objects + 7a58f25a-3dc8-4dfa-bf0f-35404273569e + 137a3255-a54e-4e4c-a9c3-e6d902b2a8bb + 471af287-d88e-43f4-9bb2-98daa088f633 + 766f518e-d29b-4814-a406-a45e5ded4a64 + e4b338fe-125d-4929-92e1-4e17c08f9b3b + f53212f5-507f-4bda-b372-34bf2b7020a3 + a38644b3-ef3b-4bc2-bf1d-8843907a4a1f + e9d20ac9-0dbc-44cb-9f48-878ae446678f + 619d4216-bdfd-4395-b679-83b02e397c53 + df7fb28b-31b3-40c8-ab8a-ec66c12ea055 + 10 + ca0ff086-508f-4122-8664-195d1a456efe + Group + + + + + + + + + + + 7f5c6c55-f846-4a08-9c9a-cfdc285cc6fe + Scribble + + + + + false + + 1581.324 + 121.5424 + + + 1705.686 + 121.5424 + + + 1705.686 + 137.0863 + + + 1581.324 + 137.0863 + + A quick note + Cambria + 766f518e-d29b-4814-a406-a45e5ded4a64 + false + Scribble + Scribble + 22 + Visualization + + + + + + 1576.324 + 116.5424 + 134.3623 + 25.54395 + + + 1581.324 + 121.5424 + + + + + + + + + + 8ec86459-bf01-4409-baee-174d0d2b13d0 + Data + + + + + Contains a collection of generic data + b96209a7-93e4-4212-b096-c83e82b4da7b + Data + Pickup plane + false + d385349b-7e03-4362-b9d0-eacd34e2562b + 1 + 2 + + + + + + 69 + 745 + 50 + 24 + + + 94.7766 + 757.5543 + + + + + + + + + + 8ec86459-bf01-4409-baee-174d0d2b13d0 + Data + + + + + Contains a collection of generic data + 98209ace-c305-4683-b351-d9b9daf31e36 + Data + Robot + false + 4e66fe1b-29b3-4955-9524-ca986decd9ac + 1 + 2 + + + + + + 70 + 709 + 50 + 24 + + + 95.8785 + 721.4962 + + + + + + + + + + 7f5c6c55-f846-4a08-9c9a-cfdc285cc6fe + Scribble + + + + + false + + 46.70692 + 861.2363 + + + 379.9403 + 861.2363 + + + 379.9403 + 881.4102 + + + 46.70692 + 881.4102 + + A quick note + Cambria + ba94b074-3f68-4274-8b84-f87aa5c4cb3e + false + Scribble + Scribble + 22 + 5) Plan trajectory to selected plane + + + + + + 41.70692 + 856.2363 + 343.2334 + 30.17383 + + + 46.70692 + 861.2363 + + + + + + + + + + 7f5c6c55-f846-4a08-9c9a-cfdc285cc6fe + Scribble + + + + + false + + 75.11641 + 888.1221 + + + 314.8351 + 888.1221 + + + 314.8351 + 902.833 + + + 75.11641 + 902.833 + + A quick note + Cambria + 01b0a494-be40-47b6-bdc4-7c92967b9f38 + false + Scribble + Scribble + 16 + From pickup config to target plane + + + + + + 70.11641 + 883.1221 + 249.7187 + 24.71094 + + + 75.11641 + 888.1221 + + + + + + + + + + 8ec86459-bf01-4409-baee-174d0d2b13d0 + Data + + + + + Contains a collection of generic data + 55db7485-e593-4762-a166-64303d976c7a + Data + Target planes + false + aacb02be-ffde-4997-b910-3a5670a6e5b1 + 1 + 2 + + + + + + 84 + 996 + 50 + 24 + + + 109.1617 + 1008.612 + + + + + + + + + + 8ec86459-bf01-4409-baee-174d0d2b13d0 + Data + + + + + Contains a collection of generic data + 538c02c6-6b3b-4712-a784-dda0bc63f847 + Data + Robot + false + 4e66fe1b-29b3-4955-9524-ca986decd9ac + 1 + 2 + + + + + + 87 + 928 + 50 + 24 + + + 112.2886 + 940.8403 + + + + + + + + + + 8ec86459-bf01-4409-baee-174d0d2b13d0 + Data + + + + + Contains a collection of generic data + c666c109-2ccb-4c50-90cd-00130af76eaa + Data + Pickup config + false + 02bc89eb-6961-419b-a5c7-ecf1d7beb296 + 1 + 2 + + + + + + 84 + 967 + 50 + 24 + + + 109.694 + 979.456 + + + + + + + + + + 57da07bd-ecab-415d-9d86-af36d7073abc + Number Slider + + + + + Numeric slider for single values + e4b338fe-125d-4929-92e1-4e17c08f9b3b + Number Slider + + false + 0 + + + + + + 1589 + 206 + 160 + 20 + + + 1589.964 + 206.742 + + + + + + 3 + 1 + 1 + 100 + 0 + 0 + 45 + + + + + + + + + 59daf374-bc21-4a5e-8282-5504fb7ae9ae + List Item + + + + + 0 + Retrieve a specific item from a list. + df7fb28b-31b3-40c8-ab8a-ec66c12ea055 + List Item + Item + + + + + + 2161 + 191 + 64 + 64 + + + 2195 + 223 + + + + + + 3 + 8ec86459-bf01-4409-baee-174d0d2b13d0 + 2e3ab970-8545-46bb-836c-1c11e5610bce + cb95db89-6165-43b6-9c41-5702bc5bf137 + 1 + 8ec86459-bf01-4409-baee-174d0d2b13d0 + + + + + 1 + Base list + 39c89e61-bc93-43d0-a501-c5bba7a3da6e + List + L + false + ddfd1927-535b-4f08-acf1-f1762fa62a54 + 1 + + + + + + 2163 + 193 + 17 + 20 + + + 2173 + 203 + + + + + + + + Item index + 83d287eb-3d9d-4785-b735-156766b364e7 + Index + i + false + e4b338fe-125d-4929-92e1-4e17c08f9b3b + 1 + + + + + + 2163 + 213 + 17 + 20 + + + 2173 + 223 + + + + + + 1 + + + + + 1 + {0} + + + + + 0 + + + + + + + + + + + Wrap index to list bounds + 60da4aea-66d4-49fc-8aa9-a5189edc913b + Wrap + W + false + 0 + + + + + + 2163 + 233 + 17 + 20 + + + 2173 + 243 + + + + + + 1 + + + + + 1 + {0} + + + + + true + + + + + + + + + + + Item at {i'} + 4ca3f55b-10fb-41c3-9f24-2b4809b96eeb + false + Item + i + false + 0 + + + + + + 2210 + 193 + 13 + 60 + + + 2216.5 + 223 + + + + + + + + + + + + + + 8ec86459-bf01-4409-baee-174d0d2b13d0 + Data + + + + + Contains a collection of generic data + bcf27a28-24e5-4d31-8438-444d7fe511cb + Data + Trajectory + false + e48f3ced-d4da-446d-ba81-c0f5e4f0e6c5 + 1 + + + + + + 1295 + 889 + 50 + 24 + + + 1320.417 + 901.836 + + + + + + + + + + 410755b1-224a-4c1e-a407-bf32fb45ea7e + 00000000-0000-0000-0000-000000000000 + GhPython Script + + + + + configs = trajectory.points + GhPython provides a Python script component + + 1122 + 357 + + + 2114 + 806 + + true + true + 2 + false + f53212f5-507f-4bda-b372-34bf2b7020a3 + false + true + GhPython Script + get configs + + + + + + 1716 + 370 + 132 + 28 + + + 1786 + 384 + + + + + + 1 + 84fa917c-1ed8-4db3-8be1-7bdc4a6495a2 + 1 + 8ec86459-bf01-4409-baee-174d0d2b13d0 + + + + + true + Script variable Python + 50f68354-3c25-4a84-a5f7-ddaf267be516 + trajectory + trajectory + true + 0 + true + e9d20ac9-0dbc-44cb-9f48-878ae446678f + 1 + 87f87f55-5b71-41f4-8aea-21d494016f81 + + + + + + 1718 + 372 + 53 + 24 + + + 1746 + 384 + + + + + + + + Script output configs. + a4b043bc-8e30-4b4c-bb40-e7f42497696d + configs + configs + false + 0 + + + + + + 1801 + 372 + 45 + 24 + + + 1823.5 + 384 + + + + + + + + + + + + + + 8ec86459-bf01-4409-baee-174d0d2b13d0 + Data + + + + + Contains a collection of generic data + a38644b3-ef3b-4bc2-bf1d-8843907a4a1f + Data + Pickup config + false + 02bc89eb-6961-419b-a5c7-ecf1d7beb296 + 1 + 2 + + + + + + 1595 + 330 + 50 + 24 + + + 1620.298 + 342.2563 + + + + + + + + + + 8ec86459-bf01-4409-baee-174d0d2b13d0 + Data + + + + + Contains a collection of generic data + e9d20ac9-0dbc-44cb-9f48-878ae446678f + Data + Trajectory + false + bcf27a28-24e5-4d31-8438-444d7fe511cb + 1 + 2 + + + + + + 1595 + 372 + 50 + 24 + + + 1620.241 + 384.8775 + + + + + + + + + + 8ec86459-bf01-4409-baee-174d0d2b13d0 + Data + + + + + Contains a collection of generic data + 619d4216-bdfd-4395-b679-83b02e397c53 + Data + Robot + false + 4e66fe1b-29b3-4955-9524-ca986decd9ac + 1 + 2 + + + + + + 1595 + 281 + 50 + 24 + + + 1620.799 + 293.1818 + + + + + + + + + + c552a431-af5b-46a9-a8a4-0fcbc27ef596 + Group + + + + + 1 + + 150;240;218;146 + + A group of Grasshopper objects + ba94b074-3f68-4274-8b84-f87aa5c4cb3e + 01b0a494-be40-47b6-bdc4-7c92967b9f38 + 55db7485-e593-4762-a166-64303d976c7a + 97392278-c93e-4240-86e9-5e59dc2eb992 + 4a09e38e-e49b-43a1-809e-f310b5a4c3e2 + 1f8b3c58-8382-468d-8885-a179a0ad05e0 + 538c02c6-6b3b-4712-a784-dda0bc63f847 + c666c109-2ccb-4c50-90cd-00130af76eaa + 13b3eb29-3c6d-41ba-80fe-d6214ebc9674 + 9d4e5cda-5bb7-42fe-acfa-968fa6c6c067 + cd76efff-9d02-4eb1-b6dd-080d6a0e6d4d + bcf27a28-24e5-4d31-8438-444d7fe511cb + 341bd723-6aaa-4369-8515-56fead3f37c8 + 815442f4-f418-45b1-8cb0-6810d7541b9c + beff27cc-8b8d-438c-a74c-3300e8d876a8 + 10e72b03-2043-4568-8435-2e9b860659bc + eb75856a-83fe-4ac8-9f03-4bf3ef7fc92e + 17 + 4c3c7466-b1c2-4942-9ac0-63cb70a5b6b7 + Group + + + + + + + + + + + 59e0b89a-e487-49f8-bab8-b5bab16be14c + Panel + + + + + A panel for custom notes and text values + ecc8c71a-07d9-4980-90b1-a3cd2f8081a6 + Panel + + false + 0 + 0 + Define multiple target planes in any way you like, for example, +reference a curve from Rhino, divide it and assign a plane to each point + +Make sure all planes are oriented in a way that makes sense +for the robot to reach it as well. + + + + + + -530 + 485 + 523 + 96 + + 0 + 0 + 0 + + + + + 3 + + 255;255;250;90 + + true + true + true + false + false + true + + + + + Courier New + 8 + + + + + + + + + + + 59e0b89a-e487-49f8-bab8-b5bab16be14c + Panel + + + + + A panel for custom notes and text values + fb166dfc-4abf-4aa5-9ecf-d86922966dfe + Panel + + false + 0 + 0 + Define one pick-up plane in any way you like, +for example, reference a point from Rhino and assign a plane to it. + +Make sure the plane is oriented in a way that makes sense +for the robot to reach it. You can check this by observing the +results of the IK solution for this pickup-plane. + + + + + + -536 + 293 + 529 + 96 + + 0 + 0 + 0 + + -535.2353 + 293.4706 + + + + + + 3 + + 255;255;250;90 + + true + true + true + false + false + true + + + + + Courier New + 8 + + + + + + + + + + + 59e0b89a-e487-49f8-bab8-b5bab16be14c + Panel + + + + + A panel for custom notes and text values + c7cc41e4-23fe-4958-87c2-e75feb10ebac + Panel + + false + 0 + 0 + Load the robot from ROS. + +Make sure ROS/MoveIt is running before you start (ie. "Compose up"). + + + + + + -536 + 124 + 529 + 96 + + 0 + 0 + 0 + + -535.2353 + 124.4706 + + + + + + 3 + + 255;255;250;90 + + true + true + true + false + false + true + + + + + Courier New + 8 + + + + + + + + + + + 59e0b89a-e487-49f8-bab8-b5bab16be14c + Panel + + + + + A panel for custom notes and text values + 3f032319-94be-407d-8e0f-7615f6976834 + Panel + + false + 0 + 0 + Use inverse kinematics of the robot to find +a feasible configuration to reach the pickup plane. + +You can use the COMPAS FAB component or +code it in a GHPython component. + + + + + + -530 + 680 + 523 + 96 + + 0 + 0 + 0 + + -529.5882 + 680.8822 + + + + + + 3 + + 255;255;250;90 + + true + true + true + false + false + true + + + + + Courier New + 8 + + + + + + + + + + + 59e0b89a-e487-49f8-bab8-b5bab16be14c + Panel + + + + + A panel for custom notes and text values + 1f02a236-cf56-4437-8d21-1243b22a7b8e + Panel + + false + 0 + 0 + With the pickup config and a list of target planes, you are ready to compute the solution trajectory for each plane. + +First create a constraint from the selected plane, then use the plan free-space motion to calculate a trajectory. + + + + + + -530 + 942 + 523 + 96 + + 0 + 0 + 0 + + -529.353 + 942.6469 + + + + + + 3 + + 255;255;250;90 + + true + true + true + false + false + true + + + + + Courier New + 8 + + + + + + + + + + + 2e78987b-9dfb-42a2-8b76-3923ac8bd91a + Boolean Toggle + + + + + Boolean (true/false) toggle + 21f041c3-ac7e-4dd3-b892-356c5a68f8d6 + Boolean Toggle + Connect + false + 0 + true + + + + + + 386 + 162 + 110 + 22 + + + + + + + + + + 2e78987b-9dfb-42a2-8b76-3923ac8bd91a + Boolean Toggle + + + + + Boolean (true/false) toggle + 6352c50d-a5bd-4d35-ba7e-cf64134ce45e + Boolean Toggle + Load robot + false + 0 + true + + + + + + 711 + 147 + 124 + 22 + + + + + + + + + + 410755b1-224a-4c1e-a407-bf32fb45ea7e + 00000000-0000-0000-0000-000000000000 + ROS Connect + + + + + """ +Connect or disconnect to ROS. + +COMPAS FAB v0.27.0 +""" +from ghpythonlib.componentbase import executingcomponent as component +from scriptcontext import sticky as st + +from compas_fab.backends import RosClient +from compas_fab.ghpython.components import create_id + + +class ROSConnect(component): + def RunScript(self, ip, port, connect): + ros_client = None + + ip = ip or '127.0.0.1' + port = port or 9090 + + key = create_id(self, 'ros_client') + ros_client = st.get(key, None) + + if ros_client: + st[key].close() + if connect: + st[key] = RosClient(ip, port) + st[key].run(5) + + ros_client = st.get(key, None) + is_connected = ros_client.is_connected if ros_client else False + return (ros_client, is_connected) + + Connect or disconnect to ROS. +COMPAS FAB v0.27.0 + true + true + 2 + + iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAALEAAACxABrSO9dQAAAdZJREFUSEu1lD2O4kAQRrkBcwP2BnADfARuABEhcAMcEEyCQKuVCCEkY27A3ADCyUAimQyHm/V+r9bNNp5iSLwtPWF/9dvdZRohhP+KK9aJK9aJK9aJKzpk4k08W4XYiB/CYquJPJbX6zVMp9PQbrcV0XhIt9sN6/VaIVZoQLyXMGVC8piYXwp5jMfj0Gq1zK/f7yvUVsdLGnkRBV0RlHT2/g2WHH+KonmJI4PD4ZA6HwVFPd9IR1hTzWZTj76Tcjay1Wr1QWIKnE6n0Ov17DnhXeSiWnTJbvHZ7/d3BkNrg3E2m/2OBbiH4XCITkLg+YhNnMVtakRuib0CWgMMYlMUxetutzPH8vwZ00f+HB8auznHe6CxagDdnMt3ztPOkunAWYsiPcF3YYxGo19ZloXtdvtT78d4b9yDVpEmf8Eg8qiJt7gLCi0WC9v2IxjV6Mu9aU3SAh2MYhI1wZaPBMcZfwadl8n5oqX8Sya7OZkhgSJoge1Xu04pE/Ot3E4hTUQBmyDB+d7ZBIU4f4INBmE+n3/meR4ul8tS2pe4+5e/91CURRjH7BuYIIYCX/vf8fgqaKYFHxEvz6CZh8nBFUGLQl7nN7y4Kq5YJ65YJ65YJ65YH6HxB7b14P1B22tpAAAAAElFTkSuQmCC + + false + c18b26bb-31cc-4a46-ad0e-d62a0b0bbaed + true + true + ROS Connect + ROS + + + + + + 530 + 121 + 153 + 64 + + + 593 + 153 + + + + + + 3 + 84fa917c-1ed8-4db3-8be1-7bdc4a6495a2 + 84fa917c-1ed8-4db3-8be1-7bdc4a6495a2 + 84fa917c-1ed8-4db3-8be1-7bdc4a6495a2 + 2 + 8ec86459-bf01-4409-baee-174d0d2b13d0 + 8ec86459-bf01-4409-baee-174d0d2b13d0 + + + + + true + The ip address ROS. Defaults to 127.0.0.1. + d16d2c83-58a3-438a-ae79-f73614483e3d + ip + ip + true + 0 + true + 0 + 37261734-eec7-4f50-b6a8-b8d1f3c4396b + + + + + + 532 + 123 + 46 + 20 + + + 556.5 + 133 + + + + + + + + true + The port of ROS. Defaults to 9090. + 4cd4f4d0-2e6d-4630-934a-dbe0ab40b7cc + port + port + true + 0 + true + 0 + 48d01794-d3d8-4aef-990e-127168822244 + + + + + + 532 + 143 + 46 + 20 + + + 556.5 + 153 + + + + + + + + true + If True, connects to ROS. If False, disconnects from ROS. Defaults to False. + 50e0fbfd-eb9b-49ac-82b8-4345728567a8 + connect + connect + true + 0 + true + 21f041c3-ac7e-4dd3-b892-356c5a68f8d6 + 1 + d60527f5-b5af-4ef6-8970-5f96fe412559 + + + + + + 532 + 163 + 46 + 20 + + + 556.5 + 173 + + + + + + + + The ROS client. + f5427eac-9b1e-4816-a202-18fc353e82bb + ros_client + ros_client + false + 0 + + + + + + 608 + 123 + 73 + 30 + + + 644.5 + 138 + + + + + + + + True if connection established. + 8b9da299-1eb0-4fa3-a9f6-f87691990e8a + is_connected + is_connected + false + 0 + + + + + + 608 + 153 + 73 + 30 + + + 644.5 + 168 + + + + + + + + + + + + + + 410755b1-224a-4c1e-a407-bf32fb45ea7e + 00000000-0000-0000-0000-000000000000 + ROS Robot + + + + + """ +Load robot directly from ROS. + +COMPAS FAB v0.27.0 +""" +from compas_ghpython.artists import RobotModelArtist +from ghpythonlib.componentbase import executingcomponent as component +from scriptcontext import sticky as st + +from compas_fab.ghpython.components import create_id + + +class ROSRobot(component): + def RunScript(self, ros_client, load): + key = create_id(self, 'robot') + + if ros_client and ros_client.is_connected and load: + # Load URDF from ROS + st[key] = ros_client.load_robot(load_geometry=True, precision='12f') + st[key].artist = RobotModelArtist(st[key].model) + + robot = st.get(key, None) + if robot: # client sometimes need to be restarted, without needing to reload geometry + robot.client = ros_client + return robot + + Load robot directly from ROS. +COMPAS FAB v0.27.0 + true + true + 2 + + iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAALEAAACxABrSO9dQAAAVtJREFUSEu9lMFRwzAQRVMCJaSElJASUgIlUAGTEhguXHPinBJSAiWkBDow/9n6ZmWtQzwYduaNpdVqtf5redN13Z+SOtckdS5B9iCeeKbrmXMJsrNg8CkOzXo1Gao5iYtg4z6uR2SP4iqY+Ans3Y5xk00sTjfsBcmOgbjOmMK2wvs/mgNKQL8o3sRzmb8Iy5BRySLbifHNpwsM3gWHvJY5ByAb44xKRtkoTz+vJkNiBn7CQXAIr29oqNd7OWTIhHxMrmNOD0oQb2EdSYL2VUUlDjlJ5kKQMDa8lahsdEPdNFfUHFLiiYsNJ766D9WG3lHLYy7TOCOjEArLi2gcQ7ATR2bvxC1yZ/7VjI1bQu4cXjt+KeaYxd8idQLJQmLDoelPbY7UaWTxCzGnLHaO1Glkv2546xhubUz2E8i2m+YxreP7Ji9htvmt4x8O4Ffhn9q93C/R2qTO9eg2XxfZxOCoCLXEAAAAAElFTkSuQmCC + + false + 85690ecd-5df2-4a09-8ae9-1fcfd8464052 + true + true + ROS Robot + Robot + + + + + + 884 + 126 + 124 + 44 + + + 954 + 148 + + + + + + 2 + 84fa917c-1ed8-4db3-8be1-7bdc4a6495a2 + 84fa917c-1ed8-4db3-8be1-7bdc4a6495a2 + 1 + 8ec86459-bf01-4409-baee-174d0d2b13d0 + + + + + true + The ROS client. + a3468000-ddbf-473d-a5d9-7a6c14c11f19 + ros_client + ros_client + true + 0 + true + f5427eac-9b1e-4816-a202-18fc353e82bb + 1 + 87f87f55-5b71-41f4-8aea-21d494016f81 + + + + + + 886 + 128 + 53 + 20 + + + 914 + 138 + + + + + + + + true + If True, loads the robot from ROS. Defaults to False. + 8c35a88e-6757-4e98-b814-f0b4d5a6415f + load + load + true + 0 + true + 6352c50d-a5bd-4d35-ba7e-cf64134ce45e + 1 + d60527f5-b5af-4ef6-8970-5f96fe412559 + + + + + + 886 + 148 + 53 + 20 + + + 914 + 158 + + + + + + + + The robot. + aa5456e2-dffb-4ba4-82cb-38af4281a720 + robot + robot + false + 0 + + + + + + 969 + 128 + 37 + 40 + + + 987.5 + 148 + + + + + + + + + + + + + + d5967b9f-e8ee-436b-a8ad-29fdcecf32d5 + Curve + + + + + Contains a collection of generic curves + true + 4f1bc38f-6a9f-437d-8a82-533f7ce70148 + Curve + Crv + false + 0 + + + + + + 332 + 477 + 50 + 24 + + + 357.0941 + 489.2437 + + + + + + 1 + + + + + 1 + {0} + + + + + -1 + + 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 + + 00000000-0000-0000-0000-000000000000 + + + + + + + + + + + + + 2162e72e-72fc-4bf8-9459-d4d82fa8aa14 + Divide Curve + + + + + Divide a curve into equal length segments + true + 14994986-4db2-48ff-ab06-9c7e8f20c2cb + Divide Curve + Divide + + + + + + 541 + 482 + 65 + 64 + + + 573 + 514 + + + + + + Curve to divide + 103cd9aa-e32a-4830-b45b-1d25be317819 + Curve + C + false + 4f1bc38f-6a9f-437d-8a82-533f7ce70148 + 1 + + + + + + 543 + 484 + 15 + 20 + + + 552 + 494 + + + + + + + + Number of segments + 5b7957af-962f-4fee-956b-6a74e9ab9ece + Count + N + false + 84402150-f07d-4183-9fbe-6ea14415688b + 1 + + + + + + 543 + 504 + 15 + 20 + + + 552 + 514 + + + + + + 1 + + + + + 1 + {0} + + + + + 10 + + + + + + + + + + + Split segments at kinks + b9ecd6a2-a721-4412-b3b6-d03f79b18b59 + Kinks + K + false + 0 + + + + + + 543 + 524 + 15 + 20 + + + 552 + 534 + + + + + + 1 + + + + + 1 + {0} + + + + + false + + + + + + + + + + + 1 + Division points + d4fe7725-550b-4973-a1b9-7fc61539adf9 + Points + P + false + 0 + + + + + + 588 + 484 + 16 + 20 + + + 596 + 494 + + + + + + + + 1 + Tangent vectors at division points + 13d8e3be-ff00-4185-a962-9d28a01cf7de + Tangents + T + false + 0 + + + + + + 588 + 504 + 16 + 20 + + + 596 + 514 + + + + + + + + 1 + Parameter values at division points + 30e7c6d6-c663-487f-9b6a-ab25864d6689 + Parameters + t + false + 0 + + + + + + 588 + 524 + 16 + 20 + + + 596 + 534 + + + + + + + + + + + + fbac3e32-f100-4292-8692-77240a42fd1a + Point + + + + + Contains a collection of three-dimensional points + true + 5235608a-4b5e-4183-a054-5f9d8217431b + Point + Pt + false + d4fe7725-550b-4973-a1b9-7fc61539adf9 + 1 + + + + + + 652 + 517 + 50 + 24 + + + 677.4901 + 529.8375 + + + + + + 1 + + + + + 1 + {0} + + + + + + + 0.759716405316307 + 0.0526028502330617 + 0.401755888009535 + + + + + + + + + + + + + + fbac3e32-f100-4292-8692-77240a42fd1a + Point + + + + + Contains a collection of three-dimensional points + true + a77c8eab-6595-484c-89c7-f3ac58bfaaca + Point + Pt + false + 0 + + + + + + 318 + 313 + 50 + 24 + + + 343.9037 + 325.0151 + + + + + + 1 + + + + + 1 + {0} + + + + + + + -0.0513345009551205 + -0.568736292517306 + 0 + + + + + + + + + + + + + + 17b7152b-d30d-4d50-b9ef-c9fe25576fc2 + XY Plane + + + + + World XY plane. + true + 99413aec-4eda-476f-b718-55fe92447c4c + XY Plane + XY + + + + + + 400 + 315 + 65 + 28 + + + 432 + 329 + + + + + + Origin of plane + 9d32ebc6-10ff-4353-942e-7326a6cd8092 + Origin + O + false + a77c8eab-6595-484c-89c7-f3ac58bfaaca + 1 + + + + + + 402 + 317 + 15 + 24 + + + 411 + 329 + + + + + + 1 + + + + + 1 + {0} + + + + + + + 0 + 0 + 0 + + + + + + + + + + + + World XY plane + 25bda67c-6e41-49c0-ba81-ab75f0c071e4 + Plane + P + false + 0 + + + + + + 447 + 317 + 16 + 24 + + + 455 + 329 + + + + + + + + + + + + c73e1ed0-82a2-40b0-b4df-8f10e445d60b + Flip Plane + + + + + Flip or swap the axes of a plane + 88b33553-efec-4a46-8e23-7956b6fb9c82 + Flip Plane + PFlip + + + + + + 500 + 317 + 64 + 84 + + + 531 + 359 + + + + + + Plane to adjust + aa5e502d-37cb-4be7-a2dc-4fa488c1be06 + Plane + P + false + 25bda67c-6e41-49c0-ba81-ab75f0c071e4 + 1 + + + + + + 502 + 319 + 14 + 20 + + + 510.5 + 329 + + + + + + 1 + + + + + 1 + {0} + + + + + + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 1 + 0 + + + + + + + + + + + + Reverse the x-axis direction + cf4f1509-9cbc-44f9-9fe6-5d37af937c2d + Reverse X + X + false + 0 + + + + + + 502 + 339 + 14 + 20 + + + 510.5 + 349 + + + + + + 1 + + + + + 1 + {0} + + + + + false + + + + + + + + + + + Reverse the y-axis direction + bc48ef09-f73a-4d5e-bc5a-725c2caa9f31 + Reverse Y + Y + false + 0 + + + + + + 502 + 359 + 14 + 20 + + + 510.5 + 369 + + + + + + 1 + + + + + 1 + {0} + + + + + false + + + + + + + + + + + Swap the x and y axis directions + 51e09346-bf3b-49c6-a69e-4e7a9ae81c5e + Swap axes + S + false + 0 + + + + + + 502 + 379 + 14 + 20 + + + 510.5 + 389 + + + + + + 1 + + + + + 1 + {0} + + + + + true + + + + + + + + + + + Flipped plane + bc441cf5-1159-4fe7-b3bc-3b1cac9ac3f4 + Plane + P + false + 0 + + + + + + 546 + 319 + 16 + 80 + + + 554 + 359 + + + + + + + + + + + + c73e1ed0-82a2-40b0-b4df-8f10e445d60b + Flip Plane + + + + + Flip or swap the axes of a plane + 66286210-f9f4-4f8b-b98e-aefaa50e8f02 + Flip Plane + PFlip + + + + + + 882 + 477 + 64 + 84 + + + 913 + 519 + + + + + + Plane to adjust + f0c103d4-5e1d-4efd-96ae-203e3ffb2571 + Plane + P + false + 9d2c3210-6596-42aa-a4cc-f535ed355d06 + 1 + + + + + + 884 + 479 + 14 + 20 + + + 892.5 + 489 + + + + + + 1 + + + + + 1 + {0} + + + + + + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 1 + 0 + + + + + + + + + + + + Reverse the x-axis direction + c90863a5-ef67-4fdf-a6c3-24aa61259514 + Reverse X + X + false + 0 + + + + + + 884 + 499 + 14 + 20 + + + 892.5 + 509 + + + + + + 1 + + + + + 1 + {0} + + + + + false + + + + + + + + + + + Reverse the y-axis direction + cdecf6f9-b4ed-47a1-bcdc-cef196612d71 + Reverse Y + Y + false + 0 + + + + + + 884 + 519 + 14 + 20 + + + 892.5 + 529 + + + + + + 1 + + + + + 1 + {0} + + + + + false + + + + + + + + + + + Swap the x and y axis directions + 81aa130c-ee3c-456e-9255-45342485dd2b + Swap axes + S + false + 0 + + + + + + 884 + 539 + 14 + 20 + + + 892.5 + 549 + + + + + + 1 + + + + + 1 + {0} + + + + + true + + + + + + + + + + + Flipped plane + 33d8782b-58a4-4217-9659-139215119c80 + Plane + P + false + 0 + + + + + + 928 + 479 + 16 + 80 + + + 936 + 519 + + + + + + + + + + + + 410755b1-224a-4c1e-a407-bf32fb45ea7e + 00000000-0000-0000-0000-000000000000 + Inverse Kinematics + + + + + """ +Calculate the robot's inverse kinematic for a given plane. + +COMPAS FAB v0.27.0 +""" +from compas_rhino.conversions import RhinoPlane +from ghpythonlib.componentbase import executingcomponent as component + + +class InverseKinematics(component): + def RunScript(self, robot, plane, start_configuration, group): + configuration = None + if robot and robot.client and robot.client.is_connected and plane: + frame = RhinoPlane.from_geometry(plane).to_compas_frame() + configuration = robot.inverse_kinematics(frame, start_configuration, group) + return configuration + + Calculate the robot's inverse kinematic for a given plane. +COMPAS FAB v0.27.0 + true + true + 2 + + iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAACxIAAAsSAdLdfvwAAAGBSURBVEhLtZSxccMwDEVVp/IAKTSCigzgLm26pNQIHkET+DSCRtAIKjKAqtQaQRsw/8sADZGwLd3ZuHsn8JMARBJSEUJ4Ka74TFxxC+/n39LTU1xRQZIajCAIM+jBt/gHL87iigyUREw6gRY0oBNNOXnxFldEIBMyQZfoLPwnc2S08x6ZgKBKgnvVYDVo3j4+f6BzJ9wdd8Z1d+8iEyRBDIR9ATrK6liwbrkH2BFUdm7RUwEBA5h0DGsAnck8mcwmHgAHhH68/FVyguTL9nUM6yRQC1g8jbQxXh0FydMjsm83A97HCVid2J0Mms8rUEqB5ZJhugM+V30PYzE6LGyL3i5AkJxtqgUYPKdrZO4g8xxYYiNkQRaYvmFs2RRYBUZZx2LNat4OUmC9BNbe/BZckcC4fTok6++t+OIluV6ue/5byYWiKIGeqbLp1+yRC9dWsx9R/HD2kgvXxPxFtOLHvt5LLuTHQ2626SNy4dLX9uOh/5Iu4r/l6M3vwRWfRyj+AbsLc3z7FG5SAAAAAElFTkSuQmCC + + false + d6aa3cd1-1856-4140-9204-fc16b23a82d0 + true + true + Inverse Kinematics + IK + + + + + + 508 + 700 + 207 + 84 + + + 623 + 742 + + + + + + 4 + 84fa917c-1ed8-4db3-8be1-7bdc4a6495a2 + 84fa917c-1ed8-4db3-8be1-7bdc4a6495a2 + 84fa917c-1ed8-4db3-8be1-7bdc4a6495a2 + 84fa917c-1ed8-4db3-8be1-7bdc4a6495a2 + 1 + 8ec86459-bf01-4409-baee-174d0d2b13d0 + + + + + true + The robot. + 043c7fd3-4595-4249-b6f6-258331a70ff8 + robot + robot + true + 0 + true + 98209ace-c305-4683-b351-d9b9daf31e36 + 1 + 87f87f55-5b71-41f4-8aea-21d494016f81 + 2 + + + + + + 510 + 702 + 98 + 20 + + + 560.5 + 712 + + + + + + + + true + The plane or frame to calculate the inverse kinematic for. + 263417f2-85f6-425f-804b-b451d2678319 + plane + plane + true + 0 + true + b96209a7-93e4-4212-b096-c83e82b4da7b + 1 + 87f87f55-5b71-41f4-8aea-21d494016f81 + + + + + + 510 + 722 + 98 + 20 + + + 560.5 + 732 + + + + + + + + true + If passed, calculates the inverse such that the joint positions differ the least from the start_configuration. Defaults to the zero configuration. + 144351c6-d883-47cb-bd20-e49d57b12eda + start_configuration + start_configuration + true + 0 + true + 0 + 87f87f55-5b71-41f4-8aea-21d494016f81 + + + + + + 510 + 742 + 98 + 20 + + + 560.5 + 752 + + + + + + + + true + The planning group used for calculation. Defaults to the robot's main planning group. + a4059939-d5f2-4135-b5ac-1d820f53b015 + group + group + true + 0 + true + 0 + 37261734-eec7-4f50-b6a8-b8d1f3c4396b + + + + + + 510 + 762 + 98 + 20 + + + 560.5 + 772 + + + + + + + + The planning group's configuration. + 4cba6477-f3c9-45a8-b24e-d6b1c262c1d6 + configuration + configuration + false + 0 + + + + + + 638 + 702 + 75 + 80 + + + 675.5 + 742 + + + + + + + + + + + + + + 410755b1-224a-4c1e-a407-bf32fb45ea7e + 00000000-0000-0000-0000-000000000000 + Constraints From Plane + + + + + """ +Create a position and an orientation constraint from a plane calculated for the group's end-effector link. + +COMPAS FAB v0.27.0 +""" +import math + +from compas_rhino.conversions import RhinoPlane +from ghpythonlib.componentbase import executingcomponent as component + + +class ConstraintsFromPlane(component): + def RunScript(self, robot, plane, group, tolerance_position, tolerance_xaxis, tolerance_yaxis, tolerance_zaxis): + goal_constraints = None + if robot and plane: + tolerance_position = tolerance_position or 0.001 + tolerance_xaxis = tolerance_xaxis or 1. + tolerance_yaxis = tolerance_yaxis or 1. + tolerance_zaxis = tolerance_zaxis or 1. + + frame = RhinoPlane.from_geometry(plane).to_compas_frame() + tolerances_axes = [math.radians(tolerance_xaxis), math.radians(tolerance_yaxis), math.radians(tolerance_zaxis)] + goal_constraints = robot.constraints_from_frame(frame, tolerance_position, tolerances_axes, group) + + return goal_constraints + + Create a position and an orientation constraint from a plane calculated for the group's end-effector link. +COMPAS FAB v0.27.0 + + 73 + 73 + + + 3386 + 1664 + + true + true + 2 + + iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAACxEAAAsRAX9kX5EAAAHfSURBVEhLtZUxS8NAGIaPdhDUoVRRxNaeCC4qZHAV6g8QOjkHx04Z/AEZOzgUHV3yD8zslMFBcCn4B0onwSVO4nS+3/Uu3LVfm1RweMjde/meL7mcVSil/hU2nEWI5waXV4ENXSCXYMitVYENXSAPwYhbqwIbukCeAgz+tk1s6AJxbhr0uPUy2NACaWDkRMLdUwYbWiCNnAZj7p4y2NACaeY0ICR33zLY0AXSGGTcWhXY0GVZg6OODMHS5mxIvAjRpeumeBqs1dM3GotH0QXFcYU8BhjO11vYEPIQKDC4aV18iyBWECdgAkbypN2HeERyQw4SMPeNvAnhyC1J8070Ic6B2rnankqlnOCa6fFUbhsFrq9MTkQQN8DXxu26llOT+n3t/fD4YEBzqsW1axp4PyuL5DlITaZfGw16nbPWZ+e0/VN7qNGWqa3r5odtQGAc0RwUf/VW3gMZiID3igQK6On0BwWvaDTcu9xN2+f7uoFZI/QbAdq6mGo90SJMsd6eVaBaVrgIFNEeF+ceY++YYkxvSvLIZkVxFVA4NILQzGcb2KOrvxvhCcpAYQOMjYTktiE9uZUXT094gipAIIE9/y60fZ6c8CarAFkAbCP6TWL/480FqwCpPr7c2hQlfgEp2YYU5C2cFwAAAABJRU5ErkJggg== + + false + 341bd723-6aaa-4369-8515-56fead3f37c8 + true + true + Constraints From Plane + Constraints From Plane + + + + + + 692 + 907 + 193 + 144 + + + 805 + 979 + + + + + + 7 + 84fa917c-1ed8-4db3-8be1-7bdc4a6495a2 + 84fa917c-1ed8-4db3-8be1-7bdc4a6495a2 + 84fa917c-1ed8-4db3-8be1-7bdc4a6495a2 + 84fa917c-1ed8-4db3-8be1-7bdc4a6495a2 + 84fa917c-1ed8-4db3-8be1-7bdc4a6495a2 + 84fa917c-1ed8-4db3-8be1-7bdc4a6495a2 + 84fa917c-1ed8-4db3-8be1-7bdc4a6495a2 + 1 + 8ec86459-bf01-4409-baee-174d0d2b13d0 + + + + + true + The robot. + 7d4b9e2a-f429-46fd-9c7f-dbf5b31279a5 + robot + robot + true + 0 + true + 538c02c6-6b3b-4712-a784-dda0bc63f847 + 1 + 87f87f55-5b71-41f4-8aea-21d494016f81 + 2 + + + + + + 694 + 909 + 96 + 20 + + + 743.5 + 919 + + + + + + + + true + The plane or frame from which we create position and orientation constraints. + b5eb509b-cdd1-4fba-a73a-a2a824ca9215 + plane + plane + true + 0 + true + eb75856a-83fe-4ac8-9f03-4bf3ef7fc92e + 1 + 87f87f55-5b71-41f4-8aea-21d494016f81 + + + + + + 694 + 929 + 96 + 20 + + + 743.5 + 939 + + + + + + + + true + The planning group for which we specify the constraint. Defaults to the robot's main planning group. + b572ada9-a2da-4dc9-87a1-45dd7c2a865d + group + group + true + 0 + true + 0 + 37261734-eec7-4f50-b6a8-b8d1f3c4396b + + + + + + 694 + 949 + 96 + 20 + + + 743.5 + 959 + + + + + + + + true + The allowed tolerance to the frame's position (defined in the robot's units). Defaults to 0.001 + 76f8e33a-ce55-46f1-92dc-9902928ef9c1 + tolerance_position + tolerance_position + true + 0 + true + 0 + 39fbc626-7a01-46ab-a18e-ec1c0c41685b + + + + + + 694 + 969 + 96 + 20 + + + 743.5 + 979 + + + + + + + + true + The allowed tolerance of the frame's X-axis in degrees. + 24e653a8-573e-4604-b6be-23aee65533c8 + tolerance_xaxis + tolerance_xaxis + true + 0 + true + 0 + 39fbc626-7a01-46ab-a18e-ec1c0c41685b + + + + + + 694 + 989 + 96 + 20 + + + 743.5 + 999 + + + + + + + + true + The allowed tolerance of the frame's Y-axis in degrees. + 67dc1160-0349-4fa9-8fe9-590a64621e32 + tolerance_yaxis + tolerance_yaxis + true + 0 + true + 0 + 39fbc626-7a01-46ab-a18e-ec1c0c41685b + + + + + + 694 + 1009 + 96 + 20 + + + 743.5 + 1019 + + + + + + + + true + The allowed tolerance of the frame's Z-axis in degrees. + db56def1-5a3f-4f77-a942-e00fbcd2f5e3 + tolerance_zaxis + tolerance_zaxis + true + 0 + true + 0 + 39fbc626-7a01-46ab-a18e-ec1c0c41685b + + + + + + 694 + 1029 + 96 + 20 + + + 743.5 + 1039 + + + + + + + + A list containing a position and an orientation constraint. + 6cb44b71-f7a3-43a9-b910-58395c807229 + constraints + constraints + false + 0 + + + + + + 820 + 909 + 63 + 140 + + + 851.5 + 979 + + + + + + + + + + + + + + 410755b1-224a-4c1e-a407-bf32fb45ea7e + 00000000-0000-0000-0000-000000000000 + Plan Motion + + + + + """ +Calculate a motion path. + +COMPAS FAB v0.27.0 +""" +from ghpythonlib.componentbase import executingcomponent as component +from scriptcontext import sticky as st + +from compas_fab.ghpython.components import create_id + + +class PlanMotion(component): + def RunScript(self, robot, goal_constraints, start_configuration, group, attached_collision_meshes, path_constraints, planner_id, compute): + + key = create_id(self, 'trajectory') + + path_constraints = list(path_constraints) if path_constraints else None + attached_collision_meshes = list(attached_collision_meshes) if attached_collision_meshes else None + planner_id = str(planner_id) if planner_id else 'RRTConnect' + + if robot and robot.client and robot.client.is_connected and start_configuration and goal_constraints and compute: + st[key] = robot.plan_motion(goal_constraints, + start_configuration=start_configuration, + group=group, + options=dict( + attached_collision_meshes=attached_collision_meshes, + path_constraints=path_constraints, + planner_id=planner_id, + )) + + trajectory = st.get(key, None) + return trajectory + + Calculate a motion path. +COMPAS FAB v0.27.0 + true + true + 2 + + iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAACxIAAAsSAdLdfvwAAAGNSURBVEhLtZTNbQIxEIUpgQ5ICRTAgRJyibimBErgEIkaInGgAyiBDpICuOeYnHJByuZ93vFm7B0SQBtLH4znPeO/MaOmaf6VMDkkYXJIwuS1qI3FVhzEXsw7zRs9ajOxE5tI96i9CgJPmuTcgLUzvokN32e89yJ7PfukBwMmxqcgwY+fLD4G/pVpNYekBwNeBD/4JGaWYxICdjOp/FPTalZJ92YbkFdbnL3ag+Do1j5vWr0L7mSctMD8bqa0epenQgjefd7pd2IORb7otGe/FAufN408gbqlBmocI4srd1502rIk6K1SjcnRl7Vmet55utwuX3T+PoYjmoh2SHEQ/DoBx8Ak4eNSC1dpGmOLe0v5LmgviWqAR29yHnbwJeoK49UTQLG7bKCWP8yQ2Xqj+fIj5C6692B9gpP3J80M/EER1Ex7A9odEKRXrcbbeBYc7a7nN1O+3Jqips27EEzCffhxvQeY/Onjih2Yn5rPBUEirKzkTR8X3sEt/AQXVNEthMkhCZNDEiaHoxl9A6glDpIGAdZaAAAAAElFTkSuQmCC + + false + 815442f4-f418-45b1-8cb0-6810d7541b9c + true + true + Plan Motion + Plan Motion + + + + + + 1081 + 833 + 224 + 164 + + + 1232 + 915 + + + + + + 8 + 84fa917c-1ed8-4db3-8be1-7bdc4a6495a2 + 84fa917c-1ed8-4db3-8be1-7bdc4a6495a2 + 84fa917c-1ed8-4db3-8be1-7bdc4a6495a2 + 84fa917c-1ed8-4db3-8be1-7bdc4a6495a2 + 84fa917c-1ed8-4db3-8be1-7bdc4a6495a2 + 84fa917c-1ed8-4db3-8be1-7bdc4a6495a2 + 84fa917c-1ed8-4db3-8be1-7bdc4a6495a2 + 84fa917c-1ed8-4db3-8be1-7bdc4a6495a2 + 1 + 8ec86459-bf01-4409-baee-174d0d2b13d0 + + + + + true + The robot. + eee424cd-26da-4939-a722-16a478d3031a + robot + robot + true + 0 + true + 538c02c6-6b3b-4712-a784-dda0bc63f847 + 1 + 87f87f55-5b71-41f4-8aea-21d494016f81 + 2 + + + + + + 1083 + 835 + 134 + 20 + + + 1151.5 + 845 + + + + + + + + 1 + true + The goal to be achieved, defined in a set of constraints. Constraints can be very specific, for example defining value domains for each joint, such that the goal configuration is included, or defining a volume in space, to which a specific robot link (e.g. the end-effector) is required to move to. + f9c75cd2-3d04-402e-8ea1-d041e2fbf991 + goal_constraints + goal_constraints + true + 1 + true + 6cb44b71-f7a3-43a9-b910-58395c807229 + 1 + 87f87f55-5b71-41f4-8aea-21d494016f81 + + + + + + 1083 + 855 + 134 + 20 + + + 1151.5 + 865 + + + + + + + + true + The robot's full configuration, i.e. values for all configurable joints of the entire robot, at the starting position. Defaults to the all-zero configuration. + 06d10192-358e-4623-9ad8-d506ee568dee + start_configuration + start_configuration + true + 0 + true + c666c109-2ccb-4c50-90cd-00130af76eaa + 1 + 87f87f55-5b71-41f4-8aea-21d494016f81 + + + + + + 1083 + 875 + 134 + 20 + + + 1151.5 + 885 + + + + + + + + true + The planning group used for calculation. Defaults to the robot's main planning group. + c58d9204-4e1a-472d-908d-2385c8dd5022 + group + group + true + 0 + true + 0 + 37261734-eec7-4f50-b6a8-b8d1f3c4396b + + + + + + 1083 + 895 + 134 + 20 + + + 1151.5 + 905 + + + + + + + + 1 + true + A list of attached collision meshes to be included for planning. + ee9312fe-99bf-4ff2-87f1-2497a5482838 + attached_collision_meshes + attached_collision_meshes + true + 1 + true + 0 + 87f87f55-5b71-41f4-8aea-21d494016f81 + + + + + + 1083 + 915 + 134 + 20 + + + 1151.5 + 925 + + + + + + + + 1 + true + Optional constraints that can be imposed along the solution path. Note that path calculation won't work if the start_configuration violates these constraints. Defaults to None. + 4e76dc31-352d-48fa-b703-10b37fbf1dce + path_constraints + path_constraints + true + 1 + true + 0 + 87f87f55-5b71-41f4-8aea-21d494016f81 + + + + + + 1083 + 935 + 134 + 20 + + + 1151.5 + 945 + + + + + + + + true + The name of the algorithm used for path planning. Defaults to 'RRTConnect' + 592c99c0-bee9-419e-9b86-ec97e226d587 + planner_id + planner_id + true + 0 + true + 0 + 37261734-eec7-4f50-b6a8-b8d1f3c4396b + + + + + + 1083 + 955 + 134 + 20 + + + 1151.5 + 965 + + + + + + + + true + If True, calculates a trajectory. + 57ee6068-fbf2-4389-ab16-8464e15d4e68 + compute + compute + true + 0 + true + be100dab-8dc7-49d6-9eab-84c6a45d729a + 1 + d60527f5-b5af-4ef6-8970-5f96fe412559 + + + + + + 1083 + 975 + 134 + 20 + + + 1151.5 + 985 + + + + + + + + The calculated trajectory. + e48f3ced-d4da-446d-ba81-c0f5e4f0e6c5 + trajectory + trajectory + false + 0 + + + + + + 1247 + 835 + 56 + 160 + + + 1275 + 915 + + + + + + + + + + + + + + 59daf374-bc21-4a5e-8282-5504fb7ae9ae + List Item + + + + + 0 + Retrieve a specific item from a list. + beff27cc-8b8d-438c-a74c-3300e8d876a8 + List Item + Item + + + + + + 454 + 989 + 64 + 64 + + + 488 + 1021 + + + + + + 3 + 8ec86459-bf01-4409-baee-174d0d2b13d0 + 2e3ab970-8545-46bb-836c-1c11e5610bce + cb95db89-6165-43b6-9c41-5702bc5bf137 + 1 + 8ec86459-bf01-4409-baee-174d0d2b13d0 + + + + + 1 + Base list + c4f913ac-aa1b-43ba-8439-b84eb4abae0b + List + L + false + 55db7485-e593-4762-a166-64303d976c7a + 1 + + + + + + 456 + 991 + 17 + 20 + + + 466 + 1001 + + + + + + + + Item index + dc80bd21-96ba-4a0f-8e45-debc88019937 + Index + i + false + 10e72b03-2043-4568-8435-2e9b860659bc + 1 + + + + + + 456 + 1011 + 17 + 20 + + + 466 + 1021 + + + + + + 1 + + + + + 1 + {0} + + + + + 0 + + + + + + + + + + + Wrap index to list bounds + 15163228-0871-4990-ae58-9c4c35f6cdb1 + Wrap + W + false + 0 + + + + + + 456 + 1031 + 17 + 20 + + + 466 + 1041 + + + + + + 1 + + + + + 1 + {0} + + + + + true + + + + + + + + + + + Item at {i'} + 39d5eae9-87a6-4cbe-8db1-4b0f7fe26554 + false + Item + i + false + 0 + + + + + + 503 + 991 + 13 + 60 + + + 509.5 + 1021 + + + + + + + + + + + + + + 57da07bd-ecab-415d-9d86-af36d7073abc + Number Slider + + + + + Numeric slider for single values + 10e72b03-2043-4568-8435-2e9b860659bc + Number Slider + + false + 0 + + + + + + 248 + 1021 + 160 + 20 + + + 248.593 + 1021.152 + + + + + + 3 + 1 + 1 + 100 + 0 + 0 + 33 + + + + + + + + + 4f8984c4-7c7a-4d69-b0a2-183cbb330d20 + Plane + + + + + Contains a collection of three-dimensional axis-systems + eb75856a-83fe-4ac8-9f03-4bf3ef7fc92e + Plane + Pln + false + 39d5eae9-87a6-4cbe-8db1-4b0f7fe26554 + 1 + + + + + + 539 + 1002 + 50 + 24 + + + 564.417 + 1014.968 + + + + + + + + + + 17b7152b-d30d-4d50-b9ef-c9fe25576fc2 + XY Plane + + + + + World XY plane. + true + b5c08a14-4c79-4084-a0e3-6a6af8002a32 + XY Plane + XY + + + + + + 753 + 489 + 65 + 28 + + + 785 + 503 + + + + + + Origin of plane + dee0e092-138f-4f56-b7f6-9d2a599b5013 + Origin + O + false + 5235608a-4b5e-4183-a054-5f9d8217431b + 1 + + + + + + 755 + 491 + 15 + 24 + + + 764 + 503 + + + + + + 1 + + + + + 1 + {0} + + + + + + + 0 + 0 + 0 + + + + + + + + + + + + World XY plane + 9d2c3210-6596-42aa-a4cc-f535ed355d06 + Plane + P + false + 0 + + + + + + 800 + 491 + 16 + 24 + + + 808 + 503 + + + + + + + + + + + + 57da07bd-ecab-415d-9d86-af36d7073abc + Number Slider + + + + + Numeric slider for single values + 84402150-f07d-4183-9fbe-6ea14415688b + Number Slider + + false + 0 + + + + + + 354 + 520 + 162 + 20 + + + 354.8 + 520.4 + + + + + + 3 + 1 + 1 + 100 + 0 + 0 + 32 + + + + + + + + + 59e0b89a-e487-49f8-bab8-b5bab16be14c + Panel + + + + + A panel for custom notes and text values + 4818672f-cacc-435c-8f41-2d9d0b82a70d + Panel + + false + 0 + bcf27a28-24e5-4d31-8438-444d7fe511cb + 1 + Double click to edit panel content… + + + + + + 1519 + 881 + 791 + 174 + + 0 + 0 + 0 + + 1519.847 + 881.6148 + + + + + + + 255;255;250;90 + + true + true + true + false + false + true + + + + + + + + + a8b97322-2d53-47cd-905e-b932c3ccd74e + Button + + + + + Button object with two values + False + True + be100dab-8dc7-49d6-9eab-84c6a45d729a + Button + Button + false + 0 + + + + + + 941 + 1007 + 103 + 22 + + + + + + + + + + + + + + + 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MPXzZVGHphpRQIeGZVDXzna7mmVQVSf8DQh55q34iz3a20Q9d8JQ5eqoptw511RNjdtYM6fmGeykXPV8d3XxeDgsiPrkz4UyUDQ6YOzMczi+cFh3ux17iJ/dL4UyobC7CaBBRPPbdZ+/aSBIXYMY6Gl6xCIsQoN5q/xK9/eIB4KShXBf93Pe1UXiPr8w5FZEo8+HMvF4LBLp9/uT3YFkdzfxz/CLpgwjCjTExAvuYG9vePqYe05C6kT0c/VyKIOIhpj4hfj5BDJEv0YvhzJERER/PyKUISIiWlgRyhARES2sCGWIiIgWVoQyRERECytCGSIiooUVoQwREdHCilCGiIhoYUUoQ0REtLAilCEiIlpYEcoQEREtrAhliIiIFlaEMkRERAsrQhkiIqKFFaEMERHRwopQhoiIaGFFKENERLSwIpQhIiJaWBHKEBERLawIZYiIiBZWhDJEREQLK0IZIiKihRWhDBER0cKKUIaIiGhhRShDRES0sCKUISIiWlgRyhARES2sCGWIiIgWVoQyRERECytCGSIiooUVoQwREdHCilCGiIhoYUUoQ0REtLAilCEiIlpYEcoQEREtrAhliIiIFlaEMkRERAsrQhkiIqKFFaEMERHRwopQhoiIaGFFKENERLSwIpQhIiJaWBHKEBERLawIZYiIiBZWhDJEREQLK0IZIiKihRWhDBER0cKKUIaIiGhhRShDRES0sCKUISIiWlgRyhARES2sCGWIiIgWVoQyRERECytCGSIiooUVoQwREdHCilCGiIhoYUUoQ0REtLAilCEiIlpYEcoQEREtrAhliIiIFlaEMkRERAsrQhkiIqKFFaEMERHRwopQhoiIaGFFKENERLSwIpQhIiJaWBHKEBERLawIZYiIiBZWhDJEREQLK0IZIiKihRWhDBER0cKKUIaIiGhhNYcyRERERAuhacoQERERLZT+w3/4/wPkxgQbLZxirAAAAABJRU5ErkJggg== + + + + + \ No newline at end of file diff --git a/lecture_04/assignment_03/karen-antorveza/assignment_03.ghx b/lecture_04/assignment_03/karen-antorveza/assignment_03.ghx new file mode 100644 index 0000000..fea2496 --- /dev/null +++ b/lecture_04/assignment_03/karen-antorveza/assignment_03.ghx @@ -0,0 +1,5718 @@ + + + + + + + + 0 + 2 + 2 + + + + + + + 1 + 0 + 7 + + + + + + c4f913db-409d-41a9-88e1-f6f90989047d + Shaded + 1 + + 100;150;0;0 + + + 100;0;150;0 + + + + + + 637527254194888879 + + assignment_03.ghx + + + + + 0 + + + + + + 1436 + 120 + + 1.53531289 + + + + + 0 + + + + + + + 0 + + + + + 1 + + + + + GhPython, Version=7.22.22255.5001, Culture=neutral, PublicKeyToken=null + 7.22.22255.5001 + + 00000000-0000-0000-0000-000000000000 + + + + + + + + + 60 + + + + + c552a431-af5b-46a9-a8a4-0fcbc27ef596 + Group + + + + + 1 + + 150;170;135;255 + + A group of Grasshopper objects + bfe572e7-d997-4c3c-8488-4e03d01804ea + b278407c-79b3-49ef-a2c8-ee682b33d9ef + 6fe2e9d2-130c-4a02-b347-a1c6b831fc5a + 9a4be73c-3082-4c74-be27-41c7c1688c53 + 4 + 3dd78fb5-3c65-4715-b2db-b9489d44fd71 + Group + + + + + + + + + + + c552a431-af5b-46a9-a8a4-0fcbc27ef596 + Group + + + + + 1 + + 150;170;135;255 + + A group of Grasshopper objects + d5ffda3e-a3ab-4688-9de8-1d9d9e2789e3 + 4b0a07e0-a378-4f92-8f0a-6c1f1fb427f2 + 1d31a79f-b7ba-423f-944c-23f606999dae + eaec99d4-5f03-4209-953f-02aee1235de3 + 4a5bf47a-b0af-4831-a451-6b776364bb7e + 5 + 5a4ca04f-0f26-4978-bcce-92edaa3c4b8e + Group + + + + + + + + + + + c552a431-af5b-46a9-a8a4-0fcbc27ef596 + Group + + + + + 1 + + 150;170;135;255 + + A group of Grasshopper objects + 781a5de8-c54c-4805-927f-519a45da032f + 4b0a07e0-a378-4f92-8f0a-6c1f1fb427f2 + 1d31a79f-b7ba-423f-944c-23f606999dae + eaec99d4-5f03-4209-953f-02aee1235de3 + 4a5bf47a-b0af-4831-a451-6b776364bb7e + 20c7f0ab-fd13-4bd7-a130-c6fe893d2a0b + 47c152bc-c823-4835-aad3-3bf5c281e892 + d19cf29a-0512-4632-b4e0-ecc00c5b8487 + 2ceac33a-a5ff-4a42-8067-32e6a2c7fbee + ac227038-eb23-4cb5-94d8-f63bb92375a4 + b3787c61-219b-4ed9-b49f-1e7dd56236b1 + b395bfb0-5717-46c4-924c-a3ba167b1e0d + 4e66fe1b-29b3-4955-9524-ca986decd9ac + 78471367-17af-4599-8661-808ba87f82a6 + bfa816f1-e4c0-482e-9515-4b540fd2f427 + 82091d9c-f1c0-4207-8d3d-b1dca673d5df + 16 + 8b8d6fbf-db19-4267-9188-c4fdd76620b6 + Group + + + + + + + + + + + 8ec86459-bf01-4409-baee-174d0d2b13d0 + Data + + + + + Contains a collection of generic data + 4e66fe1b-29b3-4955-9524-ca986decd9ac + Data + Robot + false + aa5456e2-dffb-4ba4-82cb-38af4281a720 + 1 + + + + + + 1254 + 168 + 50 + 24 + + + 1279.353 + 180.9772 + + + + + + + + + + 7f5c6c55-f846-4a08-9c9a-cfdc285cc6fe + Scribble + + + + + false + + 46.70692 + 119.7138 + + + 272.0458 + 119.7138 + + + 272.0458 + 139.8124 + + + 46.70692 + 139.8124 + + A quick note + Cambria + 82091d9c-f1c0-4207-8d3d-b1dca673d5df + false + Scribble + Scribble + 22 + 1) Load robot from ROS + + + + + + 41.70692 + 114.7138 + 235.3389 + 30.09864 + + + 46.70692 + 119.7138 + + + + + + + + + + 8ec86459-bf01-4409-baee-174d0d2b13d0 + Data + + + + + Contains a collection of generic data + aacb02be-ffde-4997-b910-3a5670a6e5b1 + Data + Target planes + false + 33d8782b-58a4-4217-9659-139215119c80 + 1 + + + + + + 1243 + 499 + 50 + 24 + + + 1268.441 + 511.8404 + + + + + + + + + + c552a431-af5b-46a9-a8a4-0fcbc27ef596 + Group + + + + + 1 + + 150;240;218;146 + + A group of Grasshopper objects + 0c3c0677-cbf3-46be-b539-e48399697bc7 + de6b7a53-8f17-48cc-bb14-1aedc473dd1c + 04770360-9eb5-44e4-911f-142deec44bdc + aacb02be-ffde-4997-b910-3a5670a6e5b1 + 50ee1702-2c6a-4092-b68b-7fd9ec30c129 + 9dbe68e7-ae2d-4df4-89a9-ae0ec5759854 + d17c9d6f-7bf6-411c-816c-4c1caad151b9 + 7 + cf91e427-c398-45be-b915-f55275cc67b7 + Group + + + + + + + + + + + 8ec86459-bf01-4409-baee-174d0d2b13d0 + Data + + + + + Contains a collection of generic data + d385349b-7e03-4362-b9d0-eacd34e2562b + Data + Pickup plane + false + bc441cf5-1159-4fe7-b3bc-3b1cac9ac3f4 + 1 + + + + + + 1241 + 348 + 50 + 24 + + + 1266.929 + 360.6916 + + + + + + + + + + c552a431-af5b-46a9-a8a4-0fcbc27ef596 + Group + + + + + 1 + + 150;240;218;146 + + A group of Grasshopper objects + d385349b-7e03-4362-b9d0-eacd34e2562b + 66c3b06d-1415-476b-875b-53498de1860a + c9e84bc7-5f07-46ef-9e42-32f7d85d0c13 + 39a429c7-2480-4ff8-8f4c-5bd8a47369a7 + 224add91-1cc7-47af-8c77-af2d42147144 + ff0bbdd7-eb5b-4ed6-a652-505db2c0ac8c + 6 + 3c032157-3bf9-40ee-9b12-e4e807d15ccc + Group + + + + + + + + + + + 7f5c6c55-f846-4a08-9c9a-cfdc285cc6fe + Scribble + + + + + false + + 46.70692 + 281.4785 + + + 269.3387 + 281.4785 + + + 269.3387 + 301.5771 + + + 46.70692 + 301.5771 + + A quick note + Cambria + ff0bbdd7-eb5b-4ed6-a652-505db2c0ac8c + false + Scribble + Scribble + 22 + 2) Define pick-up plane + + + + + + 41.70692 + 276.4785 + 232.6318 + 30.09863 + + + 46.70692 + 281.4785 + + + + + + + + + + 7f5c6c55-f846-4a08-9c9a-cfdc285cc6fe + Scribble + + + + + false + + 46.70692 + 469.1947 + + + 263.9891 + 469.1947 + + + 263.9891 + 489.4222 + + + 46.70692 + 489.4222 + + A quick note + Cambria + 9dbe68e7-ae2d-4df4-89a9-ae0ec5759854 + false + Scribble + Scribble + 22 + 3) Define target planes + + + + + + 41.70692 + 464.1947 + 227.2822 + 30.22754 + + + 46.70692 + 469.1947 + + + + + + + + + + 410755b1-224a-4c1e-a407-bf32fb45ea7e + 00000000-0000-0000-0000-000000000000 + Robot Visualize + + + + + """ +Visualizes the robot. + +COMPAS FAB v0.27.0 +""" +from compas.artists import Artist +from compas.geometry import Frame +from compas.geometry import Transformation +from compas_fab.robots import PlanningScene +from ghpythonlib.componentbase import executingcomponent as component + + +class RobotVisualize(component): + def RunScript( + self, + robot, + group, + configuration, + show_visual, + show_collision, + show_frames, + show_base_frame, + show_end_effector_frame, + show_cm, + show_acm, + ): + + visual = None + collision = None + collision_meshes = None + attached_meshes = None + frames = None + base_frame = None + ee_frame = None + + if robot: + show_visual = True if show_visual is None else show_visual + show_cm = True if show_cm is None else show_cm + show_acm = True if show_acm is None else show_acm + configuration = configuration or robot.zero_configuration() + + robot.update(configuration, visual=show_visual, collision=show_collision) + compas_frames = robot.transformed_frames(configuration, group) + + if show_visual: + visual = robot.artist.draw_visual() + + if show_collision: + collision = robot.artist.draw_collision() + + if show_base_frame: + base_compas_frame = compas_frames[0] + artist = Artist(base_compas_frame) + base_frame = artist.draw() + + if show_end_effector_frame: + ee_compas_frame = robot.forward_kinematics( + configuration, group, options=dict(solver="model") + ) + artist = Artist(ee_compas_frame) + ee_frame = artist.draw() + + if show_frames: + frames = [] + for compas_frame in compas_frames[1:]: + artist = Artist(compas_frame) + frame = artist.draw() + frames.append(frame) + + if show_cm or show_acm: + scene = PlanningScene(robot) + scene = robot.client.get_planning_scene() + + collision_meshes = [] + attached_meshes = [] + + if show_cm: + for co in scene.world.collision_objects: + header = co.header + frame_id = header.frame_id + cms = co.to_collision_meshes() + + for cm in cms: + if cm.frame != Frame.worldXY(): + t = Transformation.from_frame(cm.frame) + mesh = cm.mesh.transformed(t) + else: + mesh = cm.mesh + + collision_meshes.append(Artist(mesh).draw()) + + if show_acm: + for aco in scene.robot_state.attached_collision_objects: + for acm in aco.to_attached_collision_meshes(): + frame_id = aco.object["header"]["frame_id"] + frame = robot.forward_kinematics( + configuration, options=dict(link=frame_id) + ) + t = Transformation.from_frame(frame) + + # Local CM frame + if ( + acm.collision_mesh.frame + and acm.collision_mesh.frame != Frame.worldXY() + ): + t = t * Transformation.from_frame( + acm.collision_mesh.frame + ) + + mesh = acm.collision_mesh.mesh.transformed(t) + + attached_meshes.append(Artist(mesh).draw()) + + return ( + visual, + collision, + collision_meshes, + attached_meshes, + frames, + base_frame, + ee_frame, + ) + + Visualizes the robot. +COMPAS FAB v0.27.0 + true + true + 2 + + iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAALEQAACxEBf2RfkQAAAdhJREFUSEu1lLFKA0EQhlUIQVBMOhGLgGAtxAcIYmmRJpWNrZ2dhSCWqURtxC6VRSofIYWlhS8QyBMEOzvP/zt2jtm9VSLEg+9ud2bnn9nZu1spiuJfyRqXSdb4F3ZvX1vigmfOXzP8FQm/iEJ8iH7qjyZUIUZiIgjseb9HvjMxE4jbE4jt2Lo0CGca0BOI3Ti8nzGFdYTFv9cShAWlUzyK6zC/E9aGHFFbND8Q1c5TBwHPgiQPYU4C2uZFPVEbNa/aA9wqg5wIE2RP6AuSsH2DAzV/2Q49aRPtwzYzTW5VBXKwC+sjIvQ+qiiso52IWSG00B941CKfwA7UDs0qqiUJ61nnD5z10ffALe2hb48x8Ws88lEIhWWLqBnC4jQBRIUsStYosdxbUx6croFgAJcWo6st5sE+ruw28EiMbfs3xbjBnxWKEw8quw1SEEvEgaQtCQydWJv1zjb3OpFoisT8G2KMJNINYlBWq8t2NfQakWCKxH48cAlNg+CT8AmPvUYkCArmq82JRmydnJeCa+sbX42dvfsgPk31ogko2L7kX9m+GpcJYLXR/AzjqD0QTUDBCyWA5v5hlSTQTfWiCSiQX4X91H5l8+jUzgHeUi2oGZZN1rg8ipVvhzuVIxcFIsQAAAAASUVORK5CYII= + + false + 7a58f25a-3dc8-4dfa-bf0f-35404273569e + true + true + Robot Visualize + Robot Visualize + + + + + + 2354 + 140 + 257 + 204 + + + 2501 + 242 + + + + + + 10 + 84fa917c-1ed8-4db3-8be1-7bdc4a6495a2 + 84fa917c-1ed8-4db3-8be1-7bdc4a6495a2 + 84fa917c-1ed8-4db3-8be1-7bdc4a6495a2 + 84fa917c-1ed8-4db3-8be1-7bdc4a6495a2 + 84fa917c-1ed8-4db3-8be1-7bdc4a6495a2 + 84fa917c-1ed8-4db3-8be1-7bdc4a6495a2 + 84fa917c-1ed8-4db3-8be1-7bdc4a6495a2 + 84fa917c-1ed8-4db3-8be1-7bdc4a6495a2 + 84fa917c-1ed8-4db3-8be1-7bdc4a6495a2 + 84fa917c-1ed8-4db3-8be1-7bdc4a6495a2 + 7 + 8ec86459-bf01-4409-baee-174d0d2b13d0 + 8ec86459-bf01-4409-baee-174d0d2b13d0 + 8ec86459-bf01-4409-baee-174d0d2b13d0 + 8ec86459-bf01-4409-baee-174d0d2b13d0 + 8ec86459-bf01-4409-baee-174d0d2b13d0 + 8ec86459-bf01-4409-baee-174d0d2b13d0 + 8ec86459-bf01-4409-baee-174d0d2b13d0 + + + + + true + The robot. + 439bbb30-bb2a-4f39-bfd6-8205cd93fd09 + robot + robot + true + 0 + true + 619d4216-bdfd-4395-b679-83b02e397c53 + 1 + 87f87f55-5b71-41f4-8aea-21d494016f81 + 2 + + + + + + 2356 + 142 + 130 + 20 + + + 2422.5 + 152 + + + + + + + + true + The planning group used for end-effector and base visualization. + ad36f822-0439-4ba3-b51a-c348f6f591ec + group + group + true + 0 + true + 0 + 37261734-eec7-4f50-b6a8-b8d1f3c4396b + + + + + + 2356 + 162 + 130 + 20 + + + 2422.5 + 172 + + + + + + + + true + The robot's full configuration. + 9fb95b19-f673-4906-9998-b63a5811ea88 + configuration + configuration + true + 0 + true + 4ca3f55b-10fb-41c3-9f24-2b4809b96eeb + 1 + 87f87f55-5b71-41f4-8aea-21d494016f81 + + + + + + 2356 + 182 + 130 + 20 + + + 2422.5 + 192 + + + + + + + + true + Whether or not to show the robot's visual meshes. + 22d8ace2-7a15-4a22-9430-2f721280765e + show_visual + show_visual + true + 0 + true + 0 + d60527f5-b5af-4ef6-8970-5f96fe412559 + + + + + + 2356 + 202 + 130 + 20 + + + 2422.5 + 212 + + + + + + + + true + Whether or not to show the robot's collision meshes. + ad827435-eaa9-47db-8456-0f04c22dde3a + show_collision + show_collision + true + 0 + true + 0 + d60527f5-b5af-4ef6-8970-5f96fe412559 + + + + + + 2356 + 222 + 130 + 20 + + + 2422.5 + 232 + + + + + + + + true + Whether or not to show the robot's joint frames. + 35824dc3-741e-4a85-9d9f-f350f6328850 + show_frames + show_frames + true + 0 + true + 0 + d60527f5-b5af-4ef6-8970-5f96fe412559 + + + + + + 2356 + 242 + 130 + 20 + + + 2422.5 + 252 + + + + + + + + true + Whether or not to show the robot's base frame. + 5c36de85-2908-4ed4-8bfb-be05a5fc15a0 + show_base_frame + show_base_frame + true + 0 + true + 0 + d60527f5-b5af-4ef6-8970-5f96fe412559 + + + + + + 2356 + 262 + 130 + 20 + + + 2422.5 + 272 + + + + + + + + true + Whether or not to show the robot's end-effector frame. + 43679585-4dff-44fc-8144-04d51b6597a3 + show_end_effector_frame + show_end_effector_frame + true + 0 + true + 0 + d60527f5-b5af-4ef6-8970-5f96fe412559 + + + + + + 2356 + 282 + 130 + 20 + + + 2422.5 + 292 + + + + + + + + true + Whether or not to show the collision meshes (if any). + b0245b8b-4b25-480e-8434-34500dd361dd + show_cm + show_cm + true + 0 + true + 0 + d60527f5-b5af-4ef6-8970-5f96fe412559 + + + + + + 2356 + 302 + 130 + 20 + + + 2422.5 + 312 + + + + + + + + true + Whether or not to show the attached collision meshes (if any). + c258dd5f-afd6-4742-9840-e8ae6df45c59 + show_acm + show_acm + true + 0 + true + 0 + d60527f5-b5af-4ef6-8970-5f96fe412559 + + + + + + 2356 + 322 + 130 + 20 + + + 2422.5 + 332 + + + + + + + + Rhino meshes of the robot's visual geometry (if any). + b51fd205-41de-4772-b77b-54118aa40c2c + visual + visual + false + 0 + + + + + + 2516 + 142 + 93 + 28 + + + 2562.5 + 156.2857 + + + + + + + + Rhino meshes of the robot's collision geometry (if any). + 3fd4309e-805a-4b2a-8b39-fb39cda51d21 + collision + collision + false + 0 + + + + + + 2516 + 170 + 93 + 29 + + + 2562.5 + 184.8571 + + + + + + + + Rhino meshes of the scene's collision meshes (if any). + ba8f5aaf-7d4f-4021-b0f3-328651e5f766 + collision_meshes + collision_meshes + false + 0 + + + + + + 2516 + 199 + 93 + 28 + + + 2562.5 + 213.4286 + + + + + + + + Rhino meshes of the scene's attached collision meshes (if any). + 00b4652c-1968-4bef-b124-5b86f4dc25bc + attached_meshes + attached_meshes + false + 0 + + + + + + 2516 + 227 + 93 + 29 + + + 2562.5 + 242 + + + + + + + + The robot's joint frames as Rhino planes (if any). + 243eeb3c-e1ad-4233-9a1a-b0ec9fd1c962 + frames + frames + false + 0 + + + + + + 2516 + 256 + 93 + 28 + + + 2562.5 + 270.5714 + + + + + + + + The robot's base frame as a Rhino plane (if any). + 91fd1995-e0da-4f23-a4c6-afeefc044dee + base_frame + base_frame + false + 0 + + + + + + 2516 + 284 + 93 + 29 + + + 2562.5 + 299.1429 + + + + + + + + The robot's end-effector frame as a Rhino plane (if any). + 5a2c4711-ae2f-4f0f-b633-afc7c8fccfd2 + ee_frame + ee_frame + false + 0 + + + + + + 2516 + 313 + 93 + 29 + + + 2562.5 + 327.7143 + + + + + + + + + + + + + + 7f5c6c55-f846-4a08-9c9a-cfdc285cc6fe + Scribble + + + + + false + + 46.70691 + 651.1613 + + + 317.5712 + 651.1613 + + + 317.5712 + 671.2599 + + + 46.70691 + 671.2599 + + A quick note + Cambria + fccb98c9-c6e5-4caa-8384-ca0ddf85fd1f + false + Scribble + Scribble + 22 + 4) Solve IK for pick-up plane + + + + + + 41.70691 + 646.1613 + 280.8643 + 30.09863 + + + 46.70691 + 651.1613 + + + + + + + + + + 8ec86459-bf01-4409-baee-174d0d2b13d0 + Data + + + + + Contains a collection of generic data + 02bc89eb-6961-419b-a5c7-ecf1d7beb296 + Data + Pickup config + false + 4cba6477-f3c9-45a8-b24e-d6b1c262c1d6 + 1 + + + + + + 1243 + 708 + 50 + 24 + + + 1268.677 + 720.8832 + + + + + + + + + + 7f5c6c55-f846-4a08-9c9a-cfdc285cc6fe + Scribble + + + + + false + + 73.59003 + 675.2849 + + + 238.8635 + 675.2849 + + + 238.8635 + 689.9958 + + + 73.59003 + 689.9958 + + A quick note + Cambria + 6e5b9db8-970d-4e5b-bf3d-6ec1c492b072 + false + Scribble + Scribble + 16 + Results in pickup config + + + + + + 68.59003 + 670.2849 + 175.2734 + 24.71094 + + + 73.59003 + 675.2849 + + + + + + + + + + c552a431-af5b-46a9-a8a4-0fcbc27ef596 + Group + + + + + 1 + + 150;240;218;146 + + A group of Grasshopper objects + fccb98c9-c6e5-4caa-8384-ca0ddf85fd1f + 02bc89eb-6961-419b-a5c7-ecf1d7beb296 + 6e5b9db8-970d-4e5b-bf3d-6ec1c492b072 + fb4c5d39-e0a5-4c45-b606-72de43c589ac + b96209a7-93e4-4212-b096-c83e82b4da7b + 98209ace-c305-4683-b351-d9b9daf31e36 + d6aa3cd1-1856-4140-9204-fc16b23a82d0 + 7 + 3962a36b-d451-45d1-acb9-c99a5708db90 + Group + + + + + + + + + + + 00027467-0d24-4fa7-b178-8dc0ac5f42ec + Value List + + + + + Provides a list of preset values to choose from + 137a3255-a54e-4e4c-a9c3-e6d902b2a8bb + 2 + 3 + Value List + List + false + 0 + + + + + 0 + Pickup config + false + + + + + 1 + Trajectory + true + + + + + + 1589 + 172 + 227 + 22 + + + + + + + + + + eeafc956-268e-461d-8e73-ee05c6f72c01 + Stream Filter + + + + + Filters a collection of input streams + 471af287-d88e-43f4-9bb2-98daa088f633 + Stream Filter + Filter + + + + + + 2044 + 171 + 77 + 64 + + + 2076 + 203 + + + + + + 3 + 2e3ab970-8545-46bb-836c-1c11e5610bce + 8ec86459-bf01-4409-baee-174d0d2b13d0 + 8ec86459-bf01-4409-baee-174d0d2b13d0 + 1 + 8ec86459-bf01-4409-baee-174d0d2b13d0 + + + + + Index of Gate stream + fde7ac2c-1b3d-473c-8b2b-4addc4d52e1a + Gate + G + false + 137a3255-a54e-4e4c-a9c3-e6d902b2a8bb + 1 + + + + + + 2046 + 173 + 15 + 20 + + + 2055 + 183 + + + + + + 1 + + + + + 1 + {0} + + + + + 0 + + + + + + + + + + + 2 + Input stream at index 0 + e6a67ce5-d55f-4ec2-a44c-573291be81a5 + false + Stream 0 + 0 + true + a38644b3-ef3b-4bc2-bf1d-8843907a4a1f + 1 + + + + + + 2046 + 193 + 15 + 20 + + + 2055 + 203 + + + + + + + + 2 + Input stream at index 1 + 14985ec3-7977-426f-bc6b-ad27afc61e04 + false + Stream 1 + 1 + true + a4b043bc-8e30-4b4c-bb40-e7f42497696d + 1 + + + + + + 2046 + 213 + 15 + 20 + + + 2055 + 223 + + + + + + + + 2 + Filtered stream + ddfd1927-535b-4f08-acf1-f1762fa62a54 + false + Stream + S(1) + false + 0 + + + + + + 2091 + 173 + 28 + 60 + + + 2105 + 203 + + + + + + + + + + + + + + c552a431-af5b-46a9-a8a4-0fcbc27ef596 + Group + + + + + 1 + + 150;0;155;194 + + A group of Grasshopper objects + 7a58f25a-3dc8-4dfa-bf0f-35404273569e + 137a3255-a54e-4e4c-a9c3-e6d902b2a8bb + 471af287-d88e-43f4-9bb2-98daa088f633 + 766f518e-d29b-4814-a406-a45e5ded4a64 + e4b338fe-125d-4929-92e1-4e17c08f9b3b + f53212f5-507f-4bda-b372-34bf2b7020a3 + a38644b3-ef3b-4bc2-bf1d-8843907a4a1f + e9d20ac9-0dbc-44cb-9f48-878ae446678f + 619d4216-bdfd-4395-b679-83b02e397c53 + df7fb28b-31b3-40c8-ab8a-ec66c12ea055 + 10 + ca0ff086-508f-4122-8664-195d1a456efe + Group + + + + + + + + + + + 7f5c6c55-f846-4a08-9c9a-cfdc285cc6fe + Scribble + + + + + false + + 1581.324 + 121.5424 + + + 1705.686 + 121.5424 + + + 1705.686 + 137.0863 + + + 1581.324 + 137.0863 + + A quick note + Cambria + 766f518e-d29b-4814-a406-a45e5ded4a64 + false + Scribble + Scribble + 22 + Visualization + + + + + + 1576.324 + 116.5424 + 134.3623 + 25.54395 + + + 1581.324 + 121.5424 + + + + + + + + + + 8ec86459-bf01-4409-baee-174d0d2b13d0 + Data + + + + + Contains a collection of generic data + b96209a7-93e4-4212-b096-c83e82b4da7b + Data + Pickup plane + false + d385349b-7e03-4362-b9d0-eacd34e2562b + 1 + 2 + + + + + + 69 + 745 + 50 + 24 + + + 94.7766 + 757.5543 + + + + + + + + + + 8ec86459-bf01-4409-baee-174d0d2b13d0 + Data + + + + + Contains a collection of generic data + 98209ace-c305-4683-b351-d9b9daf31e36 + Data + Robot + false + 4e66fe1b-29b3-4955-9524-ca986decd9ac + 1 + 2 + + + + + + 70 + 709 + 50 + 24 + + + 95.8785 + 721.4962 + + + + + + + + + + 7f5c6c55-f846-4a08-9c9a-cfdc285cc6fe + Scribble + + + + + false + + 46.70692 + 861.2363 + + + 379.9403 + 861.2363 + + + 379.9403 + 881.4102 + + + 46.70692 + 881.4102 + + A quick note + Cambria + ba94b074-3f68-4274-8b84-f87aa5c4cb3e + false + Scribble + Scribble + 22 + 5) Plan trajectory to selected plane + + + + + + 41.70692 + 856.2363 + 343.2334 + 30.17383 + + + 46.70692 + 861.2363 + + + + + + + + + + 7f5c6c55-f846-4a08-9c9a-cfdc285cc6fe + Scribble + + + + + false + + 75.11641 + 888.1221 + + + 314.8351 + 888.1221 + + + 314.8351 + 902.833 + + + 75.11641 + 902.833 + + A quick note + Cambria + 01b0a494-be40-47b6-bdc4-7c92967b9f38 + false + Scribble + Scribble + 16 + From pickup config to target plane + + + + + + 70.11641 + 883.1221 + 249.7187 + 24.71094 + + + 75.11641 + 888.1221 + + + + + + + + + + 8ec86459-bf01-4409-baee-174d0d2b13d0 + Data + + + + + Contains a collection of generic data + 55db7485-e593-4762-a166-64303d976c7a + Data + Target planes + false + aacb02be-ffde-4997-b910-3a5670a6e5b1 + 1 + 2 + + + + + + 84 + 996 + 50 + 24 + + + 109.1617 + 1008.612 + + + + + + + + + + 8ec86459-bf01-4409-baee-174d0d2b13d0 + Data + + + + + Contains a collection of generic data + 538c02c6-6b3b-4712-a784-dda0bc63f847 + Data + Robot + false + 4e66fe1b-29b3-4955-9524-ca986decd9ac + 1 + 2 + + + + + + 87 + 928 + 50 + 24 + + + 112.2886 + 940.8403 + + + + + + + + + + 8ec86459-bf01-4409-baee-174d0d2b13d0 + Data + + + + + Contains a collection of generic data + c666c109-2ccb-4c50-90cd-00130af76eaa + Data + Pickup config + false + 02bc89eb-6961-419b-a5c7-ecf1d7beb296 + 1 + 2 + + + + + + 84 + 967 + 50 + 24 + + + 109.694 + 979.456 + + + + + + + + + + 57da07bd-ecab-415d-9d86-af36d7073abc + Number Slider + + + + + Numeric slider for single values + e4b338fe-125d-4929-92e1-4e17c08f9b3b + Number Slider + + false + 0 + + + + + + 1589 + 206 + 160 + 20 + + + 1589.964 + 206.742 + + + + + + 3 + 1 + 1 + 100 + 0 + 0 + 8 + + + + + + + + + 59daf374-bc21-4a5e-8282-5504fb7ae9ae + List Item + + + + + 0 + Retrieve a specific item from a list. + df7fb28b-31b3-40c8-ab8a-ec66c12ea055 + List Item + Item + + + + + + 2161 + 191 + 64 + 64 + + + 2195 + 223 + + + + + + 3 + 8ec86459-bf01-4409-baee-174d0d2b13d0 + 2e3ab970-8545-46bb-836c-1c11e5610bce + cb95db89-6165-43b6-9c41-5702bc5bf137 + 1 + 8ec86459-bf01-4409-baee-174d0d2b13d0 + + + + + 1 + Base list + 39c89e61-bc93-43d0-a501-c5bba7a3da6e + List + L + false + ddfd1927-535b-4f08-acf1-f1762fa62a54 + 1 + + + + + + 2163 + 193 + 17 + 20 + + + 2173 + 203 + + + + + + + + Item index + 83d287eb-3d9d-4785-b735-156766b364e7 + Index + i + false + e4b338fe-125d-4929-92e1-4e17c08f9b3b + 1 + + + + + + 2163 + 213 + 17 + 20 + + + 2173 + 223 + + + + + + 1 + + + + + 1 + {0} + + + + + 0 + + + + + + + + + + + Wrap index to list bounds + 60da4aea-66d4-49fc-8aa9-a5189edc913b + Wrap + W + false + 0 + + + + + + 2163 + 233 + 17 + 20 + + + 2173 + 243 + + + + + + 1 + + + + + 1 + {0} + + + + + true + + + + + + + + + + + Item at {i'} + 4ca3f55b-10fb-41c3-9f24-2b4809b96eeb + false + Item + i + false + 0 + + + + + + 2210 + 193 + 13 + 60 + + + 2216.5 + 223 + + + + + + + + + + + + + + 8ec86459-bf01-4409-baee-174d0d2b13d0 + Data + + + + + Contains a collection of generic data + bcf27a28-24e5-4d31-8438-444d7fe511cb + Data + Trajectory + false + e48f3ced-d4da-446d-ba81-c0f5e4f0e6c5 + 1 + + + + + + 1295 + 889 + 50 + 24 + + + 1320.417 + 901.836 + + + + + + + + + + 410755b1-224a-4c1e-a407-bf32fb45ea7e + 00000000-0000-0000-0000-000000000000 + GhPython Script + + + + + configs = trajectory.points + GhPython provides a Python script component + + 1122 + 357 + + + 2114 + 806 + + true + true + 2 + false + f53212f5-507f-4bda-b372-34bf2b7020a3 + false + true + GhPython Script + get configs + + + + + + 1716 + 370 + 132 + 28 + + + 1786 + 384 + + + + + + 1 + 84fa917c-1ed8-4db3-8be1-7bdc4a6495a2 + 1 + 8ec86459-bf01-4409-baee-174d0d2b13d0 + + + + + true + Script variable Python + 50f68354-3c25-4a84-a5f7-ddaf267be516 + trajectory + trajectory + true + 0 + true + e9d20ac9-0dbc-44cb-9f48-878ae446678f + 1 + 87f87f55-5b71-41f4-8aea-21d494016f81 + + + + + + 1718 + 372 + 53 + 24 + + + 1746 + 384 + + + + + + + + Script output configs. + a4b043bc-8e30-4b4c-bb40-e7f42497696d + configs + configs + false + 0 + + + + + + 1801 + 372 + 45 + 24 + + + 1823.5 + 384 + + + + + + + + + + + + + + 8ec86459-bf01-4409-baee-174d0d2b13d0 + Data + + + + + Contains a collection of generic data + a38644b3-ef3b-4bc2-bf1d-8843907a4a1f + Data + Pickup config + false + 02bc89eb-6961-419b-a5c7-ecf1d7beb296 + 1 + 2 + + + + + + 1595 + 330 + 50 + 24 + + + 1620.298 + 342.2563 + + + + + + + + + + 8ec86459-bf01-4409-baee-174d0d2b13d0 + Data + + + + + Contains a collection of generic data + e9d20ac9-0dbc-44cb-9f48-878ae446678f + Data + Trajectory + false + bcf27a28-24e5-4d31-8438-444d7fe511cb + 1 + 2 + + + + + + 1595 + 372 + 50 + 24 + + + 1620.241 + 384.8775 + + + + + + + + + + 8ec86459-bf01-4409-baee-174d0d2b13d0 + Data + + + + + Contains a collection of generic data + 619d4216-bdfd-4395-b679-83b02e397c53 + Data + Robot + false + 4e66fe1b-29b3-4955-9524-ca986decd9ac + 1 + 2 + + + + + + 1595 + 281 + 50 + 24 + + + 1620.799 + 293.1818 + + + + + + + + + + c552a431-af5b-46a9-a8a4-0fcbc27ef596 + Group + + + + + 1 + + 150;240;218;146 + + A group of Grasshopper objects + ba94b074-3f68-4274-8b84-f87aa5c4cb3e + 01b0a494-be40-47b6-bdc4-7c92967b9f38 + 55db7485-e593-4762-a166-64303d976c7a + 97392278-c93e-4240-86e9-5e59dc2eb992 + 4a09e38e-e49b-43a1-809e-f310b5a4c3e2 + 1f8b3c58-8382-468d-8885-a179a0ad05e0 + 538c02c6-6b3b-4712-a784-dda0bc63f847 + c666c109-2ccb-4c50-90cd-00130af76eaa + 13b3eb29-3c6d-41ba-80fe-d6214ebc9674 + 9d4e5cda-5bb7-42fe-acfa-968fa6c6c067 + cd76efff-9d02-4eb1-b6dd-080d6a0e6d4d + bcf27a28-24e5-4d31-8438-444d7fe511cb + 341bd723-6aaa-4369-8515-56fead3f37c8 + 815442f4-f418-45b1-8cb0-6810d7541b9c + beff27cc-8b8d-438c-a74c-3300e8d876a8 + 10e72b03-2043-4568-8435-2e9b860659bc + eb75856a-83fe-4ac8-9f03-4bf3ef7fc92e + 17 + 4c3c7466-b1c2-4942-9ac0-63cb70a5b6b7 + Group + + + + + + + + + + + 59e0b89a-e487-49f8-bab8-b5bab16be14c + Panel + + + + + A panel for custom notes and text values + ecc8c71a-07d9-4980-90b1-a3cd2f8081a6 + Panel + + false + 0 + 0 + Define multiple target planes in any way you like, for example, +reference a curve from Rhino, divide it and assign a plane to each point + +Make sure all planes are oriented in a way that makes sense +for the robot to reach it as well. + + + + + + -530 + 485 + 523 + 96 + + 0 + 0 + 0 + + + + + 3 + + 255;255;250;90 + + true + true + true + false + false + true + + + + + Courier New + 8 + + + + + + + + + + + 59e0b89a-e487-49f8-bab8-b5bab16be14c + Panel + + + + + A panel for custom notes and text values + fb166dfc-4abf-4aa5-9ecf-d86922966dfe + Panel + + false + 0 + 0 + Define one pick-up plane in any way you like, +for example, reference a point from Rhino and assign a plane to it. + +Make sure the plane is oriented in a way that makes sense +for the robot to reach it. You can check this by observing the +results of the IK solution for this pickup-plane. + + + + + + -536 + 293 + 529 + 96 + + 0 + 0 + 0 + + -535.2353 + 293.4706 + + + + + + 3 + + 255;255;250;90 + + true + true + true + false + false + true + + + + + Courier New + 8 + + + + + + + + + + + 59e0b89a-e487-49f8-bab8-b5bab16be14c + Panel + + + + + A panel for custom notes and text values + c7cc41e4-23fe-4958-87c2-e75feb10ebac + Panel + + false + 0 + 0 + Load the robot from ROS. + +Make sure ROS/MoveIt is running before you start (ie. "Compose up"). + + + + + + -536 + 124 + 529 + 96 + + 0 + 0 + 0 + + -535.2353 + 124.4706 + + + + + + 3 + + 255;255;250;90 + + true + true + true + false + false + true + + + + + Courier New + 8 + + + + + + + + + + + 59e0b89a-e487-49f8-bab8-b5bab16be14c + Panel + + + + + A panel for custom notes and text values + 3f032319-94be-407d-8e0f-7615f6976834 + Panel + + false + 0 + 0 + Use inverse kinematics of the robot to find +a feasible configuration to reach the pickup plane. + +You can use the COMPAS FAB component or +code it in a GHPython component. + + + + + + -530 + 680 + 523 + 96 + + 0 + 0 + 0 + + -529.5882 + 680.8822 + + + + + + 3 + + 255;255;250;90 + + true + true + true + false + false + true + + + + + Courier New + 8 + + + + + + + + + + + 59e0b89a-e487-49f8-bab8-b5bab16be14c + Panel + + + + + A panel for custom notes and text values + 1f02a236-cf56-4437-8d21-1243b22a7b8e + Panel + + false + 0 + 0 + With the pickup config and a list of target planes, you are ready to compute the solution trajectory for each plane. + +First create a constraint from the selected plane, then use the plan free-space motion to calculate a trajectory. + + + + + + -530 + 942 + 523 + 96 + + 0 + 0 + 0 + + -529.353 + 942.6469 + + + + + + 3 + + 255;255;250;90 + + true + true + true + false + false + true + + + + + Courier New + 8 + + + + + + + + + + + 2e78987b-9dfb-42a2-8b76-3923ac8bd91a + Boolean Toggle + + + + + Boolean (true/false) toggle + 21f041c3-ac7e-4dd3-b892-356c5a68f8d6 + Boolean Toggle + Connect + false + 0 + true + + + + + + 386 + 162 + 110 + 22 + + + + + + + + + + 2e78987b-9dfb-42a2-8b76-3923ac8bd91a + Boolean Toggle + + + + + Boolean (true/false) toggle + 6352c50d-a5bd-4d35-ba7e-cf64134ce45e + Boolean Toggle + Load robot + false + 0 + true + + + + + + 711 + 147 + 124 + 22 + + + + + + + + + + 410755b1-224a-4c1e-a407-bf32fb45ea7e + 00000000-0000-0000-0000-000000000000 + ROS Connect + + + + + """ +Connect or disconnect to ROS. + +COMPAS FAB v0.27.0 +""" +from ghpythonlib.componentbase import executingcomponent as component +from scriptcontext import sticky as st + +from compas_fab.backends import RosClient +from compas_fab.ghpython.components import create_id + + +class ROSConnect(component): + def RunScript(self, ip, port, connect): + ros_client = None + + ip = ip or '127.0.0.1' + port = port or 9090 + + key = create_id(self, 'ros_client') + ros_client = st.get(key, None) + + if ros_client: + st[key].close() + if connect: + st[key] = RosClient(ip, port) + st[key].run(5) + + ros_client = st.get(key, None) + is_connected = ros_client.is_connected if ros_client else False + return (ros_client, is_connected) + + Connect or disconnect to ROS. +COMPAS FAB v0.27.0 + true + true + 2 + + iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAALEAAACxABrSO9dQAAAdZJREFUSEu1lD2O4kAQRrkBcwP2BnADfARuABEhcAMcEEyCQKuVCCEkY27A3ADCyUAimQyHm/V+r9bNNp5iSLwtPWF/9dvdZRohhP+KK9aJK9aJK9aJKzpk4k08W4XYiB/CYquJPJbX6zVMp9PQbrcV0XhIt9sN6/VaIVZoQLyXMGVC8piYXwp5jMfj0Gq1zK/f7yvUVsdLGnkRBV0RlHT2/g2WHH+KonmJI4PD4ZA6HwVFPd9IR1hTzWZTj76Tcjay1Wr1QWIKnE6n0Ov17DnhXeSiWnTJbvHZ7/d3BkNrg3E2m/2OBbiH4XCITkLg+YhNnMVtakRuib0CWgMMYlMUxetutzPH8vwZ00f+HB8auznHe6CxagDdnMt3ztPOkunAWYsiPcF3YYxGo19ZloXtdvtT78d4b9yDVpEmf8Eg8qiJt7gLCi0WC9v2IxjV6Mu9aU3SAh2MYhI1wZaPBMcZfwadl8n5oqX8Sya7OZkhgSJoge1Xu04pE/Ot3E4hTUQBmyDB+d7ZBIU4f4INBmE+n3/meR4ul8tS2pe4+5e/91CURRjH7BuYIIYCX/vf8fgqaKYFHxEvz6CZh8nBFUGLQl7nN7y4Kq5YJ65YJ65YJ65YH6HxB7b14P1B22tpAAAAAElFTkSuQmCC + + false + c18b26bb-31cc-4a46-ad0e-d62a0b0bbaed + true + true + ROS Connect + ROS + + + + + + 530 + 121 + 153 + 64 + + + 593 + 153 + + + + + + 3 + 84fa917c-1ed8-4db3-8be1-7bdc4a6495a2 + 84fa917c-1ed8-4db3-8be1-7bdc4a6495a2 + 84fa917c-1ed8-4db3-8be1-7bdc4a6495a2 + 2 + 8ec86459-bf01-4409-baee-174d0d2b13d0 + 8ec86459-bf01-4409-baee-174d0d2b13d0 + + + + + true + The ip address ROS. Defaults to 127.0.0.1. + d16d2c83-58a3-438a-ae79-f73614483e3d + ip + ip + true + 0 + true + 0 + 37261734-eec7-4f50-b6a8-b8d1f3c4396b + + + + + + 532 + 123 + 46 + 20 + + + 556.5 + 133 + + + + + + + + true + The port of ROS. Defaults to 9090. + 4cd4f4d0-2e6d-4630-934a-dbe0ab40b7cc + port + port + true + 0 + true + 0 + 48d01794-d3d8-4aef-990e-127168822244 + + + + + + 532 + 143 + 46 + 20 + + + 556.5 + 153 + + + + + + + + true + If True, connects to ROS. If False, disconnects from ROS. Defaults to False. + 50e0fbfd-eb9b-49ac-82b8-4345728567a8 + connect + connect + true + 0 + true + 21f041c3-ac7e-4dd3-b892-356c5a68f8d6 + 1 + d60527f5-b5af-4ef6-8970-5f96fe412559 + + + + + + 532 + 163 + 46 + 20 + + + 556.5 + 173 + + + + + + + + The ROS client. + f5427eac-9b1e-4816-a202-18fc353e82bb + ros_client + ros_client + false + 0 + + + + + + 608 + 123 + 73 + 30 + + + 644.5 + 138 + + + + + + + + True if connection established. + 8b9da299-1eb0-4fa3-a9f6-f87691990e8a + is_connected + is_connected + false + 0 + + + + + + 608 + 153 + 73 + 30 + + + 644.5 + 168 + + + + + + + + + + + + + + 410755b1-224a-4c1e-a407-bf32fb45ea7e + 00000000-0000-0000-0000-000000000000 + ROS Robot + + + + + """ +Load robot directly from ROS. + +COMPAS FAB v0.27.0 +""" +from compas_ghpython.artists import RobotModelArtist +from ghpythonlib.componentbase import executingcomponent as component +from scriptcontext import sticky as st + +from compas_fab.ghpython.components import create_id + + +class ROSRobot(component): + def RunScript(self, ros_client, load): + key = create_id(self, 'robot') + + if ros_client and ros_client.is_connected and load: + # Load URDF from ROS + st[key] = ros_client.load_robot(load_geometry=True, precision='12f') + st[key].artist = RobotModelArtist(st[key].model) + + robot = st.get(key, None) + if robot: # client sometimes need to be restarted, without needing to reload geometry + robot.client = ros_client + return robot + + Load robot directly from ROS. +COMPAS FAB v0.27.0 + true + true + 2 + + iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAALEAAACxABrSO9dQAAAVtJREFUSEu9lMFRwzAQRVMCJaSElJASUgIlUAGTEhguXHPinBJSAiWkBDow/9n6ZmWtQzwYduaNpdVqtf5redN13Z+SOtckdS5B9iCeeKbrmXMJsrNg8CkOzXo1Gao5iYtg4z6uR2SP4iqY+Ans3Y5xk00sTjfsBcmOgbjOmMK2wvs/mgNKQL8o3sRzmb8Iy5BRySLbifHNpwsM3gWHvJY5ByAb44xKRtkoTz+vJkNiBn7CQXAIr29oqNd7OWTIhHxMrmNOD0oQb2EdSYL2VUUlDjlJ5kKQMDa8lahsdEPdNFfUHFLiiYsNJ766D9WG3lHLYy7TOCOjEArLi2gcQ7ATR2bvxC1yZ/7VjI1bQu4cXjt+KeaYxd8idQLJQmLDoelPbY7UaWTxCzGnLHaO1Glkv2546xhubUz2E8i2m+YxreP7Ji9htvmt4x8O4Ffhn9q93C/R2qTO9eg2XxfZxOCoCLXEAAAAAElFTkSuQmCC + + false + 85690ecd-5df2-4a09-8ae9-1fcfd8464052 + true + true + ROS Robot + Robot + + + + + + 884 + 126 + 124 + 44 + + + 954 + 148 + + + + + + 2 + 84fa917c-1ed8-4db3-8be1-7bdc4a6495a2 + 84fa917c-1ed8-4db3-8be1-7bdc4a6495a2 + 1 + 8ec86459-bf01-4409-baee-174d0d2b13d0 + + + + + true + The ROS client. + a3468000-ddbf-473d-a5d9-7a6c14c11f19 + ros_client + ros_client + true + 0 + true + f5427eac-9b1e-4816-a202-18fc353e82bb + 1 + 87f87f55-5b71-41f4-8aea-21d494016f81 + + + + + + 886 + 128 + 53 + 20 + + + 914 + 138 + + + + + + + + true + If True, loads the robot from ROS. Defaults to False. + 8c35a88e-6757-4e98-b814-f0b4d5a6415f + load + load + true + 0 + true + 6352c50d-a5bd-4d35-ba7e-cf64134ce45e + 1 + d60527f5-b5af-4ef6-8970-5f96fe412559 + + + + + + 886 + 148 + 53 + 20 + + + 914 + 158 + + + + + + + + The robot. + aa5456e2-dffb-4ba4-82cb-38af4281a720 + robot + robot + false + 0 + + + + + + 969 + 128 + 37 + 40 + + + 987.5 + 148 + + + + + + + + + + + + + + d5967b9f-e8ee-436b-a8ad-29fdcecf32d5 + Curve + + + + + Contains a collection of generic curves + true + 4f1bc38f-6a9f-437d-8a82-533f7ce70148 + Curve + Crv + false + 0 + + + + + + 332 + 477 + 50 + 24 + + + 357.0941 + 489.2437 + + + + + + 1 + + + + + 1 + {0} + + + + + -1 + + 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 + + 00000000-0000-0000-0000-000000000000 + + + + + + + + + + + + + 2162e72e-72fc-4bf8-9459-d4d82fa8aa14 + Divide Curve + + + + + Divide a curve into equal length segments + true + 14994986-4db2-48ff-ab06-9c7e8f20c2cb + Divide Curve + Divide + + + + + + 541 + 482 + 65 + 64 + + + 573 + 514 + + + + + + Curve to divide + 103cd9aa-e32a-4830-b45b-1d25be317819 + Curve + C + false + 4f1bc38f-6a9f-437d-8a82-533f7ce70148 + 1 + + + + + + 543 + 484 + 15 + 20 + + + 552 + 494 + + + + + + + + Number of segments + 5b7957af-962f-4fee-956b-6a74e9ab9ece + Count + N + false + 84402150-f07d-4183-9fbe-6ea14415688b + 1 + + + + + + 543 + 504 + 15 + 20 + + + 552 + 514 + + + + + + 1 + + + + + 1 + {0} + + + + + 10 + + + + + + + + + + + Split segments at kinks + b9ecd6a2-a721-4412-b3b6-d03f79b18b59 + Kinks + K + false + 0 + + + + + + 543 + 524 + 15 + 20 + + + 552 + 534 + + + + + + 1 + + + + + 1 + {0} + + + + + false + + + + + + + + + + + 1 + Division points + d4fe7725-550b-4973-a1b9-7fc61539adf9 + Points + P + false + 0 + + + + + + 588 + 484 + 16 + 20 + + + 596 + 494 + + + + + + + + 1 + Tangent vectors at division points + 13d8e3be-ff00-4185-a962-9d28a01cf7de + Tangents + T + false + 0 + + + + + + 588 + 504 + 16 + 20 + + + 596 + 514 + + + + + + + + 1 + Parameter values at division points + 30e7c6d6-c663-487f-9b6a-ab25864d6689 + Parameters + t + false + 0 + + + + + + 588 + 524 + 16 + 20 + + + 596 + 534 + + + + + + + + + + + + fbac3e32-f100-4292-8692-77240a42fd1a + Point + + + + + Contains a collection of three-dimensional points + true + 5235608a-4b5e-4183-a054-5f9d8217431b + Point + Pt + false + d4fe7725-550b-4973-a1b9-7fc61539adf9 + 1 + + + + + + 649 + 477 + 50 + 24 + + + 674.6 + 489.3774 + + + + + + 1 + + + + + 1 + {0} + + + + + + + 0.759716405316307 + 0.0526028502330617 + 0.401755888009535 + + + + + + + + + + + + + + fbac3e32-f100-4292-8692-77240a42fd1a + Point + + + + + Contains a collection of three-dimensional points + true + a77c8eab-6595-484c-89c7-f3ac58bfaaca + Point + Pt + false + 0 + + + + + + 318 + 313 + 50 + 24 + + + 343.9037 + 325.0151 + + + + + + 1 + + + + + 1 + {0} + + + + + + + 0.544462530512663 + 0 + 0.540682949691016 + + + + + + + + + + + + + + 17b7152b-d30d-4d50-b9ef-c9fe25576fc2 + XY Plane + + + + + World XY plane. + true + 99413aec-4eda-476f-b718-55fe92447c4c + XY Plane + XY + + + + + + 400 + 315 + 65 + 28 + + + 432 + 329 + + + + + + Origin of plane + 9d32ebc6-10ff-4353-942e-7326a6cd8092 + Origin + O + false + a77c8eab-6595-484c-89c7-f3ac58bfaaca + 1 + + + + + + 402 + 317 + 15 + 24 + + + 411 + 329 + + + + + + 1 + + + + + 1 + {0} + + + + + + + 0 + 0 + 0 + + + + + + + + + + + + World XY plane + 25bda67c-6e41-49c0-ba81-ab75f0c071e4 + Plane + P + false + 0 + + + + + + 447 + 317 + 16 + 24 + + + 455 + 329 + + + + + + + + + + + + c73e1ed0-82a2-40b0-b4df-8f10e445d60b + Flip Plane + + + + + Flip or swap the axes of a plane + 88b33553-efec-4a46-8e23-7956b6fb9c82 + Flip Plane + PFlip + + + + + + 500 + 317 + 64 + 84 + + + 531 + 359 + + + + + + Plane to adjust + aa5e502d-37cb-4be7-a2dc-4fa488c1be06 + Plane + P + false + 25bda67c-6e41-49c0-ba81-ab75f0c071e4 + 1 + + + + + + 502 + 319 + 14 + 20 + + + 510.5 + 329 + + + + + + 1 + + + + + 1 + {0} + + + + + + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 1 + 0 + + + + + + + + + + + + Reverse the x-axis direction + cf4f1509-9cbc-44f9-9fe6-5d37af937c2d + Reverse X + X + false + 0 + + + + + + 502 + 339 + 14 + 20 + + + 510.5 + 349 + + + + + + 1 + + + + + 1 + {0} + + + + + false + + + + + + + + + + + Reverse the y-axis direction + bc48ef09-f73a-4d5e-bc5a-725c2caa9f31 + Reverse Y + Y + false + 0 + + + + + + 502 + 359 + 14 + 20 + + + 510.5 + 369 + + + + + + 1 + + + + + 1 + {0} + + + + + false + + + + + + + + + + + Swap the x and y axis directions + 51e09346-bf3b-49c6-a69e-4e7a9ae81c5e + Swap axes + S + false + 0 + + + + + + 502 + 379 + 14 + 20 + + + 510.5 + 389 + + + + + + 1 + + + + + 1 + {0} + + + + + true + + + + + + + + + + + Flipped plane + bc441cf5-1159-4fe7-b3bc-3b1cac9ac3f4 + Plane + P + false + 0 + + + + + + 546 + 319 + 16 + 80 + + + 554 + 359 + + + + + + + + + + + + c73e1ed0-82a2-40b0-b4df-8f10e445d60b + Flip Plane + + + + + Flip or swap the axes of a plane + 66286210-f9f4-4f8b-b98e-aefaa50e8f02 + Flip Plane + PFlip + + + + + + 882 + 477 + 64 + 84 + + + 913 + 519 + + + + + + Plane to adjust + f0c103d4-5e1d-4efd-96ae-203e3ffb2571 + Plane + P + false + 9d2c3210-6596-42aa-a4cc-f535ed355d06 + 1 + + + + + + 884 + 479 + 14 + 20 + + + 892.5 + 489 + + + + + + 1 + + + + + 1 + {0} + + + + + + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 1 + 0 + + + + + + + + + + + + Reverse the x-axis direction + c90863a5-ef67-4fdf-a6c3-24aa61259514 + Reverse X + X + false + 0 + + + + + + 884 + 499 + 14 + 20 + + + 892.5 + 509 + + + + + + 1 + + + + + 1 + {0} + + + + + false + + + + + + + + + + + Reverse the y-axis direction + cdecf6f9-b4ed-47a1-bcdc-cef196612d71 + Reverse Y + Y + false + 0 + + + + + + 884 + 519 + 14 + 20 + + + 892.5 + 529 + + + + + + 1 + + + + + 1 + {0} + + + + + false + + + + + + + + + + + Swap the x and y axis directions + 81aa130c-ee3c-456e-9255-45342485dd2b + Swap axes + S + false + 0 + + + + + + 884 + 539 + 14 + 20 + + + 892.5 + 549 + + + + + + 1 + + + + + 1 + {0} + + + + + true + + + + + + + + + + + Flipped plane + 33d8782b-58a4-4217-9659-139215119c80 + Plane + P + false + 0 + + + + + + 928 + 479 + 16 + 80 + + + 936 + 519 + + + + + + + + + + + + 410755b1-224a-4c1e-a407-bf32fb45ea7e + 00000000-0000-0000-0000-000000000000 + Inverse Kinematics + + + + + """ +Calculate the robot's inverse kinematic for a given plane. + +COMPAS FAB v0.27.0 +""" +from compas_rhino.conversions import RhinoPlane +from ghpythonlib.componentbase import executingcomponent as component + + +class InverseKinematics(component): + def RunScript(self, robot, plane, start_configuration, group): + configuration = None + if robot and robot.client and robot.client.is_connected and plane: + frame = RhinoPlane.from_geometry(plane).to_compas_frame() + configuration = robot.inverse_kinematics(frame, start_configuration, group) + return configuration + + Calculate the robot's inverse kinematic for a given plane. +COMPAS FAB v0.27.0 + true + true + 2 + + iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAACxIAAAsSAdLdfvwAAAGBSURBVEhLtZSxccMwDEVVp/IAKTSCigzgLm26pNQIHkET+DSCRtAIKjKAqtQaQRsw/8sADZGwLd3ZuHsn8JMARBJSEUJ4Ka74TFxxC+/n39LTU1xRQZIajCAIM+jBt/gHL87iigyUREw6gRY0oBNNOXnxFldEIBMyQZfoLPwnc2S08x6ZgKBKgnvVYDVo3j4+f6BzJ9wdd8Z1d+8iEyRBDIR9ATrK6liwbrkH2BFUdm7RUwEBA5h0DGsAnck8mcwmHgAHhH68/FVyguTL9nUM6yRQC1g8jbQxXh0FydMjsm83A97HCVid2J0Mms8rUEqB5ZJhugM+V30PYzE6LGyL3i5AkJxtqgUYPKdrZO4g8xxYYiNkQRaYvmFs2RRYBUZZx2LNat4OUmC9BNbe/BZckcC4fTok6++t+OIluV6ue/5byYWiKIGeqbLp1+yRC9dWsx9R/HD2kgvXxPxFtOLHvt5LLuTHQ2626SNy4dLX9uOh/5Iu4r/l6M3vwRWfRyj+AbsLc3z7FG5SAAAAAElFTkSuQmCC + + false + d6aa3cd1-1856-4140-9204-fc16b23a82d0 + true + true + Inverse Kinematics + IK + + + + + + 508 + 700 + 207 + 84 + + + 623 + 742 + + + + + + 4 + 84fa917c-1ed8-4db3-8be1-7bdc4a6495a2 + 84fa917c-1ed8-4db3-8be1-7bdc4a6495a2 + 84fa917c-1ed8-4db3-8be1-7bdc4a6495a2 + 84fa917c-1ed8-4db3-8be1-7bdc4a6495a2 + 1 + 8ec86459-bf01-4409-baee-174d0d2b13d0 + + + + + true + The robot. + 043c7fd3-4595-4249-b6f6-258331a70ff8 + robot + robot + true + 0 + true + 98209ace-c305-4683-b351-d9b9daf31e36 + 1 + 87f87f55-5b71-41f4-8aea-21d494016f81 + 2 + + + + + + 510 + 702 + 98 + 20 + + + 560.5 + 712 + + + + + + + + true + The plane or frame to calculate the inverse kinematic for. + 263417f2-85f6-425f-804b-b451d2678319 + plane + plane + true + 0 + true + b96209a7-93e4-4212-b096-c83e82b4da7b + 1 + 87f87f55-5b71-41f4-8aea-21d494016f81 + + + + + + 510 + 722 + 98 + 20 + + + 560.5 + 732 + + + + + + + + true + If passed, calculates the inverse such that the joint positions differ the least from the start_configuration. Defaults to the zero configuration. + 144351c6-d883-47cb-bd20-e49d57b12eda + start_configuration + start_configuration + true + 0 + true + 0 + 87f87f55-5b71-41f4-8aea-21d494016f81 + + + + + + 510 + 742 + 98 + 20 + + + 560.5 + 752 + + + + + + + + true + The planning group used for calculation. Defaults to the robot's main planning group. + a4059939-d5f2-4135-b5ac-1d820f53b015 + group + group + true + 0 + true + 0 + 37261734-eec7-4f50-b6a8-b8d1f3c4396b + + + + + + 510 + 762 + 98 + 20 + + + 560.5 + 772 + + + + + + + + The planning group's configuration. + 4cba6477-f3c9-45a8-b24e-d6b1c262c1d6 + configuration + configuration + false + 0 + + + + + + 638 + 702 + 75 + 80 + + + 675.5 + 742 + + + + + + + + + + + + + + 410755b1-224a-4c1e-a407-bf32fb45ea7e + 00000000-0000-0000-0000-000000000000 + Constraints From Plane + + + + + """ +Create a position and an orientation constraint from a plane calculated for the group's end-effector link. + +COMPAS FAB v0.27.0 +""" +import math + +from compas_rhino.conversions import RhinoPlane +from ghpythonlib.componentbase import executingcomponent as component + + +class ConstraintsFromPlane(component): + def RunScript(self, robot, plane, group, tolerance_position, tolerance_xaxis, tolerance_yaxis, tolerance_zaxis): + goal_constraints = None + if robot and plane: + tolerance_position = tolerance_position or 0.001 + tolerance_xaxis = tolerance_xaxis or 1. + tolerance_yaxis = tolerance_yaxis or 1. + tolerance_zaxis = tolerance_zaxis or 1. + + frame = RhinoPlane.from_geometry(plane).to_compas_frame() + tolerances_axes = [math.radians(tolerance_xaxis), math.radians(tolerance_yaxis), math.radians(tolerance_zaxis)] + goal_constraints = robot.constraints_from_frame(frame, tolerance_position, tolerances_axes, group) + + return goal_constraints + + Create a position and an orientation constraint from a plane calculated for the group's end-effector link. +COMPAS FAB v0.27.0 + + 73 + 73 + + + 3386 + 1664 + + true + true + 2 + + iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAACxEAAAsRAX9kX5EAAAHfSURBVEhLtZUxS8NAGIaPdhDUoVRRxNaeCC4qZHAV6g8QOjkHx04Z/AEZOzgUHV3yD8zslMFBcCn4B0onwSVO4nS+3/Uu3LVfm1RweMjde/meL7mcVSil/hU2nEWI5waXV4ENXSCXYMitVYENXSAPwYhbqwIbukCeAgz+tk1s6AJxbhr0uPUy2NACaWDkRMLdUwYbWiCNnAZj7p4y2NACaeY0ICR33zLY0AXSGGTcWhXY0GVZg6OODMHS5mxIvAjRpeumeBqs1dM3GotH0QXFcYU8BhjO11vYEPIQKDC4aV18iyBWECdgAkbypN2HeERyQw4SMPeNvAnhyC1J8070Ic6B2rnankqlnOCa6fFUbhsFrq9MTkQQN8DXxu26llOT+n3t/fD4YEBzqsW1axp4PyuL5DlITaZfGw16nbPWZ+e0/VN7qNGWqa3r5odtQGAc0RwUf/VW3gMZiID3igQK6On0BwWvaDTcu9xN2+f7uoFZI/QbAdq6mGo90SJMsd6eVaBaVrgIFNEeF+ceY++YYkxvSvLIZkVxFVA4NILQzGcb2KOrvxvhCcpAYQOMjYTktiE9uZUXT094gipAIIE9/y60fZ6c8CarAFkAbCP6TWL/480FqwCpPr7c2hQlfgEp2YYU5C2cFwAAAABJRU5ErkJggg== + + false + 341bd723-6aaa-4369-8515-56fead3f37c8 + true + true + Constraints From Plane + Constraints From Plane + + + + + + 692 + 907 + 193 + 144 + + + 805 + 979 + + + + + + 7 + 84fa917c-1ed8-4db3-8be1-7bdc4a6495a2 + 84fa917c-1ed8-4db3-8be1-7bdc4a6495a2 + 84fa917c-1ed8-4db3-8be1-7bdc4a6495a2 + 84fa917c-1ed8-4db3-8be1-7bdc4a6495a2 + 84fa917c-1ed8-4db3-8be1-7bdc4a6495a2 + 84fa917c-1ed8-4db3-8be1-7bdc4a6495a2 + 84fa917c-1ed8-4db3-8be1-7bdc4a6495a2 + 1 + 8ec86459-bf01-4409-baee-174d0d2b13d0 + + + + + true + The robot. + 7d4b9e2a-f429-46fd-9c7f-dbf5b31279a5 + robot + robot + true + 0 + true + 538c02c6-6b3b-4712-a784-dda0bc63f847 + 1 + 87f87f55-5b71-41f4-8aea-21d494016f81 + 2 + + + + + + 694 + 909 + 96 + 20 + + + 743.5 + 919 + + + + + + + + true + The plane or frame from which we create position and orientation constraints. + b5eb509b-cdd1-4fba-a73a-a2a824ca9215 + plane + plane + true + 0 + true + eb75856a-83fe-4ac8-9f03-4bf3ef7fc92e + 1 + 87f87f55-5b71-41f4-8aea-21d494016f81 + + + + + + 694 + 929 + 96 + 20 + + + 743.5 + 939 + + + + + + + + true + The planning group for which we specify the constraint. Defaults to the robot's main planning group. + b572ada9-a2da-4dc9-87a1-45dd7c2a865d + group + group + true + 0 + true + 0 + 37261734-eec7-4f50-b6a8-b8d1f3c4396b + + + + + + 694 + 949 + 96 + 20 + + + 743.5 + 959 + + + + + + + + true + The allowed tolerance to the frame's position (defined in the robot's units). Defaults to 0.001 + 76f8e33a-ce55-46f1-92dc-9902928ef9c1 + tolerance_position + tolerance_position + true + 0 + true + 0 + 39fbc626-7a01-46ab-a18e-ec1c0c41685b + + + + + + 694 + 969 + 96 + 20 + + + 743.5 + 979 + + + + + + + + true + The allowed tolerance of the frame's X-axis in degrees. + 24e653a8-573e-4604-b6be-23aee65533c8 + tolerance_xaxis + tolerance_xaxis + true + 0 + true + 0 + 39fbc626-7a01-46ab-a18e-ec1c0c41685b + + + + + + 694 + 989 + 96 + 20 + + + 743.5 + 999 + + + + + + + + true + The allowed tolerance of the frame's Y-axis in degrees. + 67dc1160-0349-4fa9-8fe9-590a64621e32 + tolerance_yaxis + tolerance_yaxis + true + 0 + true + 0 + 39fbc626-7a01-46ab-a18e-ec1c0c41685b + + + + + + 694 + 1009 + 96 + 20 + + + 743.5 + 1019 + + + + + + + + true + The allowed tolerance of the frame's Z-axis in degrees. + db56def1-5a3f-4f77-a942-e00fbcd2f5e3 + tolerance_zaxis + tolerance_zaxis + true + 0 + true + 0 + 39fbc626-7a01-46ab-a18e-ec1c0c41685b + + + + + + 694 + 1029 + 96 + 20 + + + 743.5 + 1039 + + + + + + + + A list containing a position and an orientation constraint. + 6cb44b71-f7a3-43a9-b910-58395c807229 + constraints + constraints + false + 0 + + + + + + 820 + 909 + 63 + 140 + + + 851.5 + 979 + + + + + + + + + + + + + + 410755b1-224a-4c1e-a407-bf32fb45ea7e + 00000000-0000-0000-0000-000000000000 + Plan Motion + + + + + """ +Calculate a motion path. + +COMPAS FAB v0.27.0 +""" +from ghpythonlib.componentbase import executingcomponent as component +from scriptcontext import sticky as st + +from compas_fab.ghpython.components import create_id + + +class PlanMotion(component): + def RunScript(self, robot, goal_constraints, start_configuration, group, attached_collision_meshes, path_constraints, planner_id, compute): + + key = create_id(self, 'trajectory') + + path_constraints = list(path_constraints) if path_constraints else None + attached_collision_meshes = list(attached_collision_meshes) if attached_collision_meshes else None + planner_id = str(planner_id) if planner_id else 'RRTConnect' + + if robot and robot.client and robot.client.is_connected and start_configuration and goal_constraints and compute: + st[key] = robot.plan_motion(goal_constraints, + start_configuration=start_configuration, + group=group, + options=dict( + attached_collision_meshes=attached_collision_meshes, + path_constraints=path_constraints, + planner_id=planner_id, + )) + + trajectory = st.get(key, None) + return trajectory + + Calculate a motion path. +COMPAS FAB v0.27.0 + true + true + 2 + + iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAACxIAAAsSAdLdfvwAAAGNSURBVEhLtZTNbQIxEIUpgQ5ICRTAgRJyibimBErgEIkaInGgAyiBDpICuOeYnHJByuZ93vFm7B0SQBtLH4znPeO/MaOmaf6VMDkkYXJIwuS1qI3FVhzEXsw7zRs9ajOxE5tI96i9CgJPmuTcgLUzvokN32e89yJ7PfukBwMmxqcgwY+fLD4G/pVpNYekBwNeBD/4JGaWYxICdjOp/FPTalZJ92YbkFdbnL3ag+Do1j5vWr0L7mSctMD8bqa0epenQgjefd7pd2IORb7otGe/FAufN408gbqlBmocI4srd1502rIk6K1SjcnRl7Vmet55utwuX3T+PoYjmoh2SHEQ/DoBx8Ak4eNSC1dpGmOLe0v5LmgviWqAR29yHnbwJeoK49UTQLG7bKCWP8yQ2Xqj+fIj5C6692B9gpP3J80M/EER1Ex7A9odEKRXrcbbeBYc7a7nN1O+3Jqips27EEzCffhxvQeY/Onjih2Yn5rPBUEirKzkTR8X3sEt/AQXVNEthMkhCZNDEiaHoxl9A6glDpIGAdZaAAAAAElFTkSuQmCC + + false + 815442f4-f418-45b1-8cb0-6810d7541b9c + true + true + Plan Motion + Plan Motion + + + + + + 1022 + 819 + 224 + 164 + + + 1173 + 901 + + + + + + 8 + 84fa917c-1ed8-4db3-8be1-7bdc4a6495a2 + 84fa917c-1ed8-4db3-8be1-7bdc4a6495a2 + 84fa917c-1ed8-4db3-8be1-7bdc4a6495a2 + 84fa917c-1ed8-4db3-8be1-7bdc4a6495a2 + 84fa917c-1ed8-4db3-8be1-7bdc4a6495a2 + 84fa917c-1ed8-4db3-8be1-7bdc4a6495a2 + 84fa917c-1ed8-4db3-8be1-7bdc4a6495a2 + 84fa917c-1ed8-4db3-8be1-7bdc4a6495a2 + 1 + 8ec86459-bf01-4409-baee-174d0d2b13d0 + + + + + true + The robot. + eee424cd-26da-4939-a722-16a478d3031a + robot + robot + true + 0 + true + 538c02c6-6b3b-4712-a784-dda0bc63f847 + 1 + 87f87f55-5b71-41f4-8aea-21d494016f81 + 2 + + + + + + 1024 + 821 + 134 + 20 + + + 1092.5 + 831 + + + + + + + + 1 + true + The goal to be achieved, defined in a set of constraints. Constraints can be very specific, for example defining value domains for each joint, such that the goal configuration is included, or defining a volume in space, to which a specific robot link (e.g. the end-effector) is required to move to. + f9c75cd2-3d04-402e-8ea1-d041e2fbf991 + goal_constraints + goal_constraints + true + 1 + true + 6cb44b71-f7a3-43a9-b910-58395c807229 + 1 + 87f87f55-5b71-41f4-8aea-21d494016f81 + + + + + + 1024 + 841 + 134 + 20 + + + 1092.5 + 851 + + + + + + + + true + The robot's full configuration, i.e. values for all configurable joints of the entire robot, at the starting position. Defaults to the all-zero configuration. + 06d10192-358e-4623-9ad8-d506ee568dee + start_configuration + start_configuration + true + 0 + true + c666c109-2ccb-4c50-90cd-00130af76eaa + 1 + 87f87f55-5b71-41f4-8aea-21d494016f81 + + + + + + 1024 + 861 + 134 + 20 + + + 1092.5 + 871 + + + + + + + + true + The planning group used for calculation. Defaults to the robot's main planning group. + c58d9204-4e1a-472d-908d-2385c8dd5022 + group + group + true + 0 + true + 0 + 37261734-eec7-4f50-b6a8-b8d1f3c4396b + + + + + + 1024 + 881 + 134 + 20 + + + 1092.5 + 891 + + + + + + + + 1 + true + A list of attached collision meshes to be included for planning. + ee9312fe-99bf-4ff2-87f1-2497a5482838 + attached_collision_meshes + attached_collision_meshes + true + 1 + true + 0 + 87f87f55-5b71-41f4-8aea-21d494016f81 + + + + + + 1024 + 901 + 134 + 20 + + + 1092.5 + 911 + + + + + + + + 1 + true + Optional constraints that can be imposed along the solution path. Note that path calculation won't work if the start_configuration violates these constraints. Defaults to None. + 4e76dc31-352d-48fa-b703-10b37fbf1dce + path_constraints + path_constraints + true + 1 + true + 0 + 87f87f55-5b71-41f4-8aea-21d494016f81 + + + + + + 1024 + 921 + 134 + 20 + + + 1092.5 + 931 + + + + + + + + true + The name of the algorithm used for path planning. Defaults to 'RRTConnect' + 592c99c0-bee9-419e-9b86-ec97e226d587 + planner_id + planner_id + true + 0 + true + 0 + 37261734-eec7-4f50-b6a8-b8d1f3c4396b + + + + + + 1024 + 941 + 134 + 20 + + + 1092.5 + 951 + + + + + + + + true + If True, calculates a trajectory. + 57ee6068-fbf2-4389-ab16-8464e15d4e68 + compute + compute + true + 0 + true + 0 + d60527f5-b5af-4ef6-8970-5f96fe412559 + + + + + + 1024 + 961 + 134 + 20 + + + 1092.5 + 971 + + + + + + + + The calculated trajectory. + e48f3ced-d4da-446d-ba81-c0f5e4f0e6c5 + trajectory + trajectory + false + 0 + + + + + + 1188 + 821 + 56 + 160 + + + 1216 + 901 + + + + + + + + + + + + + + 59daf374-bc21-4a5e-8282-5504fb7ae9ae + List Item + + + + + 0 + Retrieve a specific item from a list. + beff27cc-8b8d-438c-a74c-3300e8d876a8 + List Item + Item + + + + + + 454 + 989 + 64 + 64 + + + 488 + 1021 + + + + + + 3 + 8ec86459-bf01-4409-baee-174d0d2b13d0 + 2e3ab970-8545-46bb-836c-1c11e5610bce + cb95db89-6165-43b6-9c41-5702bc5bf137 + 1 + 8ec86459-bf01-4409-baee-174d0d2b13d0 + + + + + 1 + Base list + c4f913ac-aa1b-43ba-8439-b84eb4abae0b + List + L + false + 55db7485-e593-4762-a166-64303d976c7a + 1 + + + + + + 456 + 991 + 17 + 20 + + + 466 + 1001 + + + + + + + + Item index + dc80bd21-96ba-4a0f-8e45-debc88019937 + Index + i + false + 10e72b03-2043-4568-8435-2e9b860659bc + 1 + + + + + + 456 + 1011 + 17 + 20 + + + 466 + 1021 + + + + + + 1 + + + + + 1 + {0} + + + + + 0 + + + + + + + + + + + Wrap index to list bounds + 15163228-0871-4990-ae58-9c4c35f6cdb1 + Wrap + W + false + 0 + + + + + + 456 + 1031 + 17 + 20 + + + 466 + 1041 + + + + + + 1 + + + + + 1 + {0} + + + + + true + + + + + + + + + + + Item at {i'} + 39d5eae9-87a6-4cbe-8db1-4b0f7fe26554 + false + Item + i + false + 0 + + + + + + 503 + 991 + 13 + 60 + + + 509.5 + 1021 + + + + + + + + + + + + + + 57da07bd-ecab-415d-9d86-af36d7073abc + Number Slider + + + + + Numeric slider for single values + 10e72b03-2043-4568-8435-2e9b860659bc + Number Slider + + false + 0 + + + + + + 248 + 1021 + 160 + 20 + + + 248.593 + 1021.152 + + + + + + 3 + 1 + 1 + 100 + 0 + 0 + 48 + + + + + + + + + 4f8984c4-7c7a-4d69-b0a2-183cbb330d20 + Plane + + + + + Contains a collection of three-dimensional axis-systems + eb75856a-83fe-4ac8-9f03-4bf3ef7fc92e + Plane + Pln + false + 39d5eae9-87a6-4cbe-8db1-4b0f7fe26554 + 1 + + + + + + 539 + 1002 + 50 + 24 + + + 564.417 + 1014.968 + + + + + + + + + + 17b7152b-d30d-4d50-b9ef-c9fe25576fc2 + XY Plane + + + + + World XY plane. + true + b5c08a14-4c79-4084-a0e3-6a6af8002a32 + XY Plane + XY + + + + + + 753 + 489 + 65 + 28 + + + 785 + 503 + + + + + + Origin of plane + dee0e092-138f-4f56-b7f6-9d2a599b5013 + Origin + O + false + 5235608a-4b5e-4183-a054-5f9d8217431b + 1 + + + + + + 755 + 491 + 15 + 24 + + + 764 + 503 + + + + + + 1 + + + + + 1 + {0} + + + + + + + 0 + 0 + 0 + + + + + + + + + + + + World XY plane + 9d2c3210-6596-42aa-a4cc-f535ed355d06 + Plane + P + false + 0 + + + + + + 800 + 491 + 16 + 24 + + + 808 + 503 + + + + + + + + + + + + 57da07bd-ecab-415d-9d86-af36d7073abc + Number Slider + + + + + Numeric slider for single values + 84402150-f07d-4183-9fbe-6ea14415688b + Number Slider + + false + 0 + + + + + + 354 + 520 + 162 + 20 + + + 354.8 + 520.4 + + + + + + 3 + 1 + 1 + 100 + 0 + 0 + 32 + + + + + + + + + 59e0b89a-e487-49f8-bab8-b5bab16be14c + Panel + + + + + A panel for custom notes and text values + 4818672f-cacc-435c-8f41-2d9d0b82a70d + Panel + + false + 0 + bcf27a28-24e5-4d31-8438-444d7fe511cb + 1 + Double click to edit panel content… + + + + + + 1519 + 881 + 791 + 174 + + 0 + 0 + 0 + + 1519.847 + 881.6148 + + + + + + + 255;255;250;90 + + true + true + true + false + false + true + + + + + + + + + + + + + + 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 + + + + + \ No newline at end of file