I have been trying to simulate a simple pendulum that can swing due to gravity after setting the initial angle. I am now able to create the urdf, and create a slider that will set the angle of the pendulum arm. But I am still facing trouble when trying to get the pendulum to move. I have been basing my code on the code present in the "Running a simple simulation" section in https://deepnote.com/project/Authoring-a-Multibody-Simulation-jnoKyVLkS5CYUgHG3ASsBA/%2Fauthor_multibody_sim.ipynb.
This is the code I have so far:
import os
from tempfile import mkdtemp
from pydrake.all import (
AddMultibodyPlantSceneGraph,
DiagramBuilder,
Meshcat,
MeshcatVisualizerCpp,
Parser,
Simulator,
)
from manipulation.meshcat_cpp_utils import (
StartMeshcat, MeshcatJointSlidersThatPublish)
meshcat = StartMeshcat("https://b8cf4725-e938-4907-9172-f08ccc4873ab.deepnoteproject.com")
tmp_dir = mkdtemp()
model_file = os.path.join(tmp_dir, "test_model.urdf")
model_text = f"""\
<?xml version="1.0"?>
<robot name="materials">
<material name="blue">
<color rgba="0 0 0.8 1"/>
</material>
<material name="white">
<color rgba="1 1 1 1"/>
</material>
<material name="green">
<color rgba="0.0 0.8 0.0 1.0"/>
</material>
<joint name="world_2_base" type="fixed">
<parent link="world"/>
<child link="base"/>
<origin xyz="0 0 0.5"/>
</joint>
<link name="base">
<visual>
<geometry>
<box size="0.5 0.5 0.1"/>
</geometry>
</visual>
<inertial>
<mass value="1"/>
</inertial>
</link>
<joint name="base" type="revolute">
<parent link="base"/>
<child link="arm"/>
<axis xyz="0 1 0"/>
<origin xyz="0 0 -0.05"/>
</joint>
<link name="arm">
<visual>
<geometry>
<cylinder length="0.5" radius="0.01"/>
</geometry>
<material name="blue"/>
<origin xyz="0 0 -0.25"/>
</visual>
<inertial>
<mass value="1"/>
</inertial>
</link>
<joint name="base2" type="fixed">
<parent link="arm"/>
<child link="ball"/>
<origin xyz="0 0 -0.5"/>
</joint>
<link name="ball">
<visual>
<geometry>
<sphere radius="0.1"/>
</geometry>
<material name="green"/>
<origin xyz="0 0 -0.01"/>
</visual>
<inertial>
<mass value="10"/>
</inertial>
</link>
</robot>
"""
# Write temporary file.
with open(model_file, "w") as f:
f.write(model_text)
builder = DiagramBuilder()
plant, scene_graph = AddMultibodyPlantSceneGraph(builder, time_step=0.0001)
# Add pendulum model.
model = Parser(plant, scene_graph).AddModelFromFile(model_file)
# - Weld base at origin.
base_link = plant.GetBodyByName("base", model)
#plant.WeldFrames(plant.world_frame(), base_link.body_frame())
plant.Finalize()
#visualizer = MeshcatVisualizerCpp.AddToBuilder(builder, scene_graph, meshcat)
visualizer = MeshcatVisualizerCpp.AddToBuilder(builder, scene_graph,
meshcat)
diagram = builder.Build()
context = diagram.CreateDefaultContext()
sliders = MeshcatJointSlidersThatPublish(meshcat, plant, visualizer, context)
pend = plant.GetBodyByName(f"base", model)
def pose_callback(context):
pose = plant.EvalBodyPoseInWorld(context, pend)
sliders.Run(pose_callback)
simulator = Simulator(diagram)
simulator.Initialize()
simulator.set_target_realtime_rate(1.0)
#visualizer.StartRecording()
simulator.AdvanceTo(5.0)
#visualizer.PublishRecording()
simulator.AdvanceTo(5.0)
Please let me know what I am doing wrong. Thank you very much
You'd need to specify a non-zero initial angle in the joint between the base and the arm to observe anything interesting. One way of doing this is
builder = DiagramBuilder()
plant, scene_graph = AddMultibodyPlantSceneGraph(builder, time_step=0.01)
# Add pendulum model.
model = Parser(plant, scene_graph).AddModelFromFile(model_file)
plant.Finalize()
joint = plant.GetJointByName('base')
joint.set_default_angle(0.2)
visualizer = MeshcatVisualizerCpp.AddToBuilder(builder, scene_graph, meshcat,
MeshcatVisualizerParams(role=Role.kIllustration, prefix="visual"))
diagram = builder.Build()
simulator = Simulator(diagram)
simulator.Initialize()
simulator.set_target_realtime_rate(1.0)
visualizer.StartRecording()
simulator.AdvanceTo(5.0)
visualizer.PublishRecording()
To set the initial condition with the slider, try
builder = DiagramBuilder()
plant, scene_graph = AddMultibodyPlantSceneGraph(builder, time_step=0.01)
# Add pendulum model.
model = Parser(plant, scene_graph).AddModelFromFile(model_file)
plant.Finalize()
visualizer = MeshcatVisualizerCpp.AddToBuilder(builder, scene_graph, meshcat,
MeshcatVisualizerParams(role=Role.kIllustration, prefix="visual"))
diagram = builder.Build()
simulator = Simulator(diagram)
# Get context of the diagram being simulated.
context = simulator.get_mutable_context()
# Set initial condition of the joint.
joint_slider = MeshcatJointSliders(meshcat, plant, context)
joint_slider.Run(visualizer, context)
# Run the simulation and record.
simulator.Initialize()
simulator.set_target_realtime_rate(1.0)
visualizer.StartRecording()
simulator.AdvanceTo(5.0)
visualizer.PublishRecording()
Before finalizing the plant, could you try calling
plant.mutable_gravity_field().set_gravity_vector([0, 0, -9.8])
?
I think you need to fix the pendulum input port to zero, you can put
diagram.get_input_port(0).FixValue(context, [0.])
after creating "context".
This says "apply zero torque at the pendulum joint actuator". So the pendulum will swing passively.
I have an svg file of the human body with groups of traces made for each muscle. I'd like to make a function that highlights certain muscles. Using regex is not the right way to go. I tried using xml but I'm not sure how to do it the right way and I'm not sure if xml truly is the right way.
This is the structure of my svg file:
<svg>
<g id="Muscles" transform="translate(-0.146 0.364)">
<g id="Abdominals">
<path id="path196" d="M3294.281-2851.382c-15.892,20.521-35.62,44.154-48.66,64.122,0,0,31.81-113.859-15.028-518.839,0,0,65.728,78.144,94.49,251.4,0,0,10.452,150.03-30.8,203.315" transform="translate(-1825.079 4663.033)" fill="#95999f"/>
<path id="path234" d="M3671.994-2915.5c15.893,20.542,35.6,44.178,48.659,64.119,0,0-23.994-49.737,22.844-454.717,0,0-65.7,78.144-94.491,251.4,0,0-18.265,85.908,22.988,139.2" transform="translate(-1494.489 4663.033)" fill="#95999f"/>
</g>
...
...
<g id="Triceps">
<path id="path198" d="M3172.882-3654.165s-144.517,96.743-129.823,251.042c14.692,154.272,59.807,225.4,10.234,308.571,0,0,127.978-21.957,152.021-141.282,24.066-119.325-28.764-221.175-32.433-418.331" transform="translate(-1975.527 4385.352)" fill="#95999f"/>
<path id="path236" d="M3832.757-3654.165s144.494,96.743,129.8,251.042c-14.694,154.272-59.806,225.4-10.236,308.571,0,0-127.952-21.957-152.02-141.282s28.787-221.175,32.456-418.331" transform="translate(-1375.567 4385.352)" fill="#95999f"/>
</g>
</g>
</svg>
I'm trying to change the color of a given muscles.
Can you do that:
let abd = document.getElementById("Abdominals").getElementsByTagName("path")
for (let path of abd) {
path.setAttribute("fill", "red");
}
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="1066.48291015625 731.18701171875 1521.556640625 1144.586181640625" version="1.1" >
<g id="Muscles" transform="translate(-0.146 0.364)">
<g id="Abdominals">
<path id="path196" d="M3294.281-2851.382c-15.892,20.521-35.62,44.154-48.66,64.122,0,0,31.81-113.859-15.028-518.839,0,0,65.728,78.144,94.49,251.4,0,0,10.452,150.03-30.8,203.315" transform="translate(-1825.079 4663.033)" fill="#95999f"/>
<path id="path234" d="M3671.994-2915.5c15.893,20.542,35.6,44.178,48.659,64.119,0,0-23.994-49.737,22.844-454.717,0,0-65.7,78.144-94.491,251.4,0,0-18.265,85.908,22.988,139.2" transform="translate(-1494.489 4663.033)" fill="#95999f"/>
</g>
<g id="Triceps">
<path id="path198" d="M3172.882-3654.165s-144.517,96.743-129.823,251.042c14.692,154.272,59.807,225.4,10.234,308.571,0,0,127.978-21.957,152.021-141.282,24.066-119.325-28.764-221.175-32.433-418.331" transform="translate(-1975.527 4385.352)" fill="#95999f"/>
<path id="path236" d="M3832.757-3654.165s144.494,96.743,129.8,251.042c-14.694,154.272-59.806,225.4-10.236,308.571,0,0-127.952-21.957-152.02-141.282s28.787-221.175,32.456-418.331" transform="translate(-1375.567 4385.352)" fill="#95999f"/>
</g>
</g>
</svg>
It's the easiest way e.g. to get your path elements via their IDs and then change their attributes as usual. You don't have to change attributes of all path children elements of your groups since you retrieve their entire collection etc.
How can I make a shape, specifically a path bigger, relevant to its position. There is something called scale but it doesn't help me because it's based on x and y which makes the shape bigger relevant to the corner. I want the shape to be zoomed in, from where it's placed, from its center.
Edit: I don't have the positions of the shapes. I have the shapes with their d attribute but I don't know how to read the centers.
Any help would be appreciated.
Transformation commands in SVG transform attributes can be concatenated - they are after all only matrices. What you can do is first translate the object to the origin of the coordinate system, then scale it, and then translate it back.
Suppose the center of your element is at (20, 30) and you want to zoom by factor 2.5. This is executed right to left (read it as a matrix multiplication):
transform="translate(20, 30) scale(2.5) translate(-20, -30)"
You can also compute the transformation matrix yourself and write:
transform="matrix(2.5,0,0,2.5,-30,-45)"
The description of these matrices is here.
In theory, with CSS transforms it should be much easier to to this. Unfortunately, browser support is not what it should be.
The following example works in Chrome, but not in Firefox (see this bug for a squabble about what is the right behaviour), IE or Edge. Stand-alone renderers also probably will fail (I falsified with librsvg and Inkscape). The green duck should be half the size of the yellow one and have the same center:
path {
fill: none;
stroke: yellow;
}
#tr {
transform: scale(0.5);
transform-origin: 50% 50%;
transform-box: fill-box;
stroke: green;
}
<svg xmlns="http://www.w3.org/2000/svg" width="250" height="250" viewBox="0 0 250 250">
<path d="M 80.1339,33.7725 A 5.6922,6.4401 10 0 1 84.6212,41.103 5.6922,6.4401 10 0 1 77.8974,46.4568 5.6922,6.4401 10 0 1 73.4101,39.1262 5.6922,6.4401 10 0 1 80.1339,33.7725 Z M 82.0104,33.2778 A 11.4192,8.81609 89.1419 0 1 89.2916,46.4615 11.4192,8.81609 89.1419 0 1 79.1684,55.7873 11.4192,8.81609 89.1419 0 1 71.8879,42.6048 11.4192,8.81609 89.1419 0 1 82.0104,33.2778 Z M 70.3671,75.3594 C 70.3671,75.3594 68.586,75.6931 67.6718,75.6488 66.3528,75.5858 65.0527,74.9422 63.7318,74.8554 59.5513,74.5845 55.4963,76.5847 51.338,75.751 49.2598,75.3338 46.915,74.5923 45.4932,72.8885 44.8341,72.1001 44.3774,70.8894 44.6455,69.9567 45.3964,67.3505 50.7912,65.0483 50.7912,65.0483 50.7912,65.0483 43.9322,61.4587 41.1061,58.7996 38.902,56.7243 36.8574,54.2568 35.6903,51.4657 34.9382,49.6678 34.0963,47.4509 34.8214,45.7744 38.1361,41.2573 43.6807,43.9856 48.4204,45.1849 50.2853,45.6599 52.1398,46.8724 53.9981,46.6994 56.7267,46.4454 58.9343,44.5042 61.1832,43.0426 63.0639,41.8215 66.407,38.8022 66.407,38.8022 66.407,38.8022 64.6497,42.5145 64.3908,44.5758 64.1223,46.7147 64.4954,48.9637 64.9058,51.1399 65.3999,53.7626 66.3032,56.3275 67.233,58.8573 68.3474,61.8899 70.6024,64.6149 71.1153,67.7638 71.5329,70.3313 70.3671,75.3594 70.3671,75.3594 Z M 92.0698,111.853 C 96.2371,106.866 102.147,102.36 108.753,101.964 118.689,101.368 127.519,112.44 137.557,113.607 146.856,114.686 164.63,109.061 164.63,109.061 164.63,109.061 162.709,125.647 158.397,132.099 153,140.178 144.607,146.556 135.357,149.419 127.645,151.807 118.626,151.276 110.573,148.601 103.65,146.302 96.4513,142.201 92.0379,136.07 89.1835,132.103 87.9619,126.816 88.1408,122.105 88.2839,118.339 89.7715,114.602 92.0698,111.853 Z M 59.2917,139.294 C 61.9445,152.369 70.7633,164.205 81.6223,170.584 100.669,181.776 125.118,181.36 145.114,176.023 160.645,171.877 176.151,163.182 185.972,150.351 176.606,158.799 164.621,164.73 152.614,167.936 132.62,173.272 108.172,173.689 89.1233,162.496 78.2648,156.116 70.8095,151.141 68.1586,138.066 66.9416,125.527 79.8773,92.7348 77.4125,94.0907 74.9457,95.445 56.1332,122.504 59.2917,139.294 Z M 65.8609,39.1294 C 70.807,28.9425 79.9895,21.2775 90.0829,19.1926 112.001,16.8358 127.033,28.7634 131.73,48.0754 133.639,55.9048 132.499,64.4111 129.685,71.5142 127.542,76.9213 118.907,84.7996 118.907,84.7996 L 113.696,88.961 C 113.696,88.961 124.423,86.1023 129.998,86.5796 137.334,87.207 144.159,92.3433 151.484,93.3861 153.944,93.7365 156.655,94.179 158.824,93.1744 162.32,91.5568 164.447,87.8071 166.49,84.4927 168.56,81.135 167.572,75.2572 170.993,73.3938 173.665,71.9378 177.805,72.9562 180.38,75.0348 188.826,81.8552 191.576,94.4359 193.393,105.027 195.625,118.046 196.35,132.764 190.351,143.692 181.279,160.216 163.201,171.195 145.113,176.024 125.117,181.361 100.67,181.776 81.6235,170.584 70.7644,164.204 61.9435,152.369 59.2917,139.294 V 139.294 C 57.7803,120.107 70.3787,106.356 76.2899,91.5133 77.2688,88.9676 78.3913,83.5238 78.3913,83.5238 74.9247,81.427 72.0301,78.643 69.6902,75.4715" />
<path id="tr" d="M 80.1339,33.7725 A 5.6922,6.4401 10 0 1 84.6212,41.103 5.6922,6.4401 10 0 1 77.8974,46.4568 5.6922,6.4401 10 0 1 73.4101,39.1262 5.6922,6.4401 10 0 1 80.1339,33.7725 Z M 82.0104,33.2778 A 11.4192,8.81609 89.1419 0 1 89.2916,46.4615 11.4192,8.81609 89.1419 0 1 79.1684,55.7873 11.4192,8.81609 89.1419 0 1 71.8879,42.6048 11.4192,8.81609 89.1419 0 1 82.0104,33.2778 Z M 70.3671,75.3594 C 70.3671,75.3594 68.586,75.6931 67.6718,75.6488 66.3528,75.5858 65.0527,74.9422 63.7318,74.8554 59.5513,74.5845 55.4963,76.5847 51.338,75.751 49.2598,75.3338 46.915,74.5923 45.4932,72.8885 44.8341,72.1001 44.3774,70.8894 44.6455,69.9567 45.3964,67.3505 50.7912,65.0483 50.7912,65.0483 50.7912,65.0483 43.9322,61.4587 41.1061,58.7996 38.902,56.7243 36.8574,54.2568 35.6903,51.4657 34.9382,49.6678 34.0963,47.4509 34.8214,45.7744 38.1361,41.2573 43.6807,43.9856 48.4204,45.1849 50.2853,45.6599 52.1398,46.8724 53.9981,46.6994 56.7267,46.4454 58.9343,44.5042 61.1832,43.0426 63.0639,41.8215 66.407,38.8022 66.407,38.8022 66.407,38.8022 64.6497,42.5145 64.3908,44.5758 64.1223,46.7147 64.4954,48.9637 64.9058,51.1399 65.3999,53.7626 66.3032,56.3275 67.233,58.8573 68.3474,61.8899 70.6024,64.6149 71.1153,67.7638 71.5329,70.3313 70.3671,75.3594 70.3671,75.3594 Z M 92.0698,111.853 C 96.2371,106.866 102.147,102.36 108.753,101.964 118.689,101.368 127.519,112.44 137.557,113.607 146.856,114.686 164.63,109.061 164.63,109.061 164.63,109.061 162.709,125.647 158.397,132.099 153,140.178 144.607,146.556 135.357,149.419 127.645,151.807 118.626,151.276 110.573,148.601 103.65,146.302 96.4513,142.201 92.0379,136.07 89.1835,132.103 87.9619,126.816 88.1408,122.105 88.2839,118.339 89.7715,114.602 92.0698,111.853 Z M 59.2917,139.294 C 61.9445,152.369 70.7633,164.205 81.6223,170.584 100.669,181.776 125.118,181.36 145.114,176.023 160.645,171.877 176.151,163.182 185.972,150.351 176.606,158.799 164.621,164.73 152.614,167.936 132.62,173.272 108.172,173.689 89.1233,162.496 78.2648,156.116 70.8095,151.141 68.1586,138.066 66.9416,125.527 79.8773,92.7348 77.4125,94.0907 74.9457,95.445 56.1332,122.504 59.2917,139.294 Z M 65.8609,39.1294 C 70.807,28.9425 79.9895,21.2775 90.0829,19.1926 112.001,16.8358 127.033,28.7634 131.73,48.0754 133.639,55.9048 132.499,64.4111 129.685,71.5142 127.542,76.9213 118.907,84.7996 118.907,84.7996 L 113.696,88.961 C 113.696,88.961 124.423,86.1023 129.998,86.5796 137.334,87.207 144.159,92.3433 151.484,93.3861 153.944,93.7365 156.655,94.179 158.824,93.1744 162.32,91.5568 164.447,87.8071 166.49,84.4927 168.56,81.135 167.572,75.2572 170.993,73.3938 173.665,71.9378 177.805,72.9562 180.38,75.0348 188.826,81.8552 191.576,94.4359 193.393,105.027 195.625,118.046 196.35,132.764 190.351,143.692 181.279,160.216 163.201,171.195 145.113,176.024 125.117,181.361 100.67,181.776 81.6235,170.584 70.7644,164.204 61.9435,152.369 59.2917,139.294 V 139.294 C 57.7803,120.107 70.3787,106.356 76.2899,91.5133 77.2688,88.9676 78.3913,83.5238 78.3913,83.5238 74.9247,81.427 72.0301,78.643 69.6902,75.4715" />
</svg>