Skip to content
LIBRARY
PlanarMechanics.SensorsTest.md

PlanarMechanics.SensorsTest

Sensor test with two free-falling bodies: validates all 6 sensor types.

Translates the "Sensors (two free falling bodies)" test from test_PlanarMechanics.jl. Two bodies (m=1, I=1) start at the origin with zero velocity and fall under gravity. A fixed base sits at the origin. Three absolute sensors are attached to body1, and six relative sensors measure pairs (body1-vs-base and body1-vs-body2).

Usage

MultibodyComponents.PlanarMechanics.SensorsTest()

Behavior

[connect(body1+framea,abspos_sensor+frame_a)connect(body1+framea,absv_sensor+frame_a)connect(body1+framea,absa_sensor+frame_a)connect(body1+framea,relpos_sensor1+frame_a)connect(world+frameb,relpos_sensor1+frame_b)connect(body1+framea,relpos_sensor2+frame_a)connect(body2+framea,relpos_sensor2+frame_b,distance+frameb)connect(world+frameb,relv_sensor1+frame_a)connect(body1+framea,relv_sensor1+frame_b)connect(body1+framea,relv_sensor2+frame_a)connect(body2+framea,relv_sensor2+frame_b)connect(body1+framea,rela_sensor1+frame_a)connect(world+frameb,rela_sensor1+frame_b)connect(rela_sensor2+frame_a,body1+framea,distance+framea)connect(body2+framea,rela_sensor2+frame_b)world.frameb.x(t)=0world.frameb.y(t)=0world.frameb.phi(t)=0connect(frameb,framevis+frame_a)world.framevis.phi(t)=world.framevis.frame_a.phi(t)world.framevis.x_shape.r(t)=arrayliteral([3],world.framevis.frame_a.x(t),world.framevis.frame_a.y(t),world.framevis.z_position)world.framevis.x_shape.R(t)=arrayliteral([33],cos(world.framevis.phi(t)),sin(world.framevis.phi(t)),0,sin(world.framevis.phi(t)),cos(world.framevis.phi(t)),0,0,0,1)world.framevis.x_shape.r_shape(t)=[000]world.framevis.x_shape.length_direction(t)=[100]world.framevis.x_shape.width_direction(t)=[001]world.framevis.x_shape.length(t)=world.framevis.axis_lengthworld.framevis.x_shape.width(t)=2world.framevis.axis_radiusworld.framevis.x_shape.height(t)=2world.framevis.axis_radiusworld.framevis.y_shape.r(t)=arrayliteral([3],world.framevis.frame_a.x(t),world.framevis.frame_a.y(t),world.framevis.z_position)world.framevis.y_shape.R(t)=arrayliteral([33],cos(world.framevis.phi(t)),sin(world.framevis.phi(t)),0,sin(world.framevis.phi(t)),cos(world.framevis.phi(t)),0,0,0,1)world.framevis.y_shape.r_shape(t)=[000]world.framevis.y_shape.length_direction(t)=[010]world.framevis.y_shape.width_direction(t)=[001]world.framevis.y_shape.length(t)=world.framevis.axis_lengthworld.framevis.y_shape.width(t)=2world.framevis.axis_radiusworld.framevis.y_shape.height(t)=2world.framevis.axis_radiusworld.framevis.z_shape.r(t)=arrayliteral([3],world.framevis.frame_a.x(t),world.framevis.frame_a.y(t),world.framevis.z_position)world.framevis.z_shape.R(t)=arrayliteral([33],cos(world.framevis.phi(t)),sin(world.framevis.phi(t)),0,sin(world.framevis.phi(t)),cos(world.framevis.phi(t)),0,0,0,1)world.framevis.z_shape.r_shape(t)=[000]world.framevis.z_shape.length_direction(t)=[001]world.framevis.z_shape.width_direction(t)=[100]world.framevis.z_shape.length(t)=world.framevis.axis_lengthworld.framevis.z_shape.width(t)=2world.framevis.axis_radiusworld.framevis.z_shape.height(t)=2world.framevis.axis_radiusbody1.r(t)=arrayliteral([2],body1.framea.x(t),body1.framea.y(t))body1.v(t)=dbody1.r(t)dtbody1.phi(t)=body1.framea.phi(t)body1.w(t)=dbody1.phi(t)dtbody1.a(t)=dbody1.v(t)dtbody1.alpha(t)=dbody1.w(t)dtbody1.f(t)=arrayliteral([2],body1.framea.fx(t),body1.framea.fy(t))arrayliteral([2],body1.mgn2d1,body1.mgn2d2)+body1.f(t)=body1.mbody1.a(t)body1.Ibody1.alpha(t)=body1.framea.tau(t)body1.shape.r(t)=arrayliteral([3],body1.framea.x(t),body1.framea.y(t),body1.zposition)body1.shape.R(t)=arrayliteral([33],cos(body1.phi(t)),sin(body1.phi(t)),0,sin(body1.phi(t)),cos(body1.phi(t)),0,0,0,1)body1.shape.rshape(t)=[000]body1.shape.lengthdirection(t)=[001]body1.shape.widthdirection(t)=[100]body1.shape.length(t)=2body1.radiusbody1.shape.width(t)=2body1.radiusbody1.shape.height(t)=2body1.radiusbody2.r(t)=arrayliteral([2],body2.framea.x(t),body2.framea.y(t))body2.v(t)=dbody2.r(t)dtbody2.phi(t)=body2.framea.phi(t)body2.w(t)=dbody2.phi(t)dtbody2.a(t)=dbody2.v(t)dtbody2.alpha(t)=dbody2.w(t)dtbody2.f(t)=arrayliteral([2],body2.framea.fx(t),body2.framea.fy(t))arrayliteral([2],body2.mgn2d1,body2.mgn2d2)+body2.f(t)=body2.mbody2.a(t)body2.Ibody2.alpha(t)=body2.framea.tau(t)body2.shape.r(t)=arrayliteral([3],body2.framea.x(t),body2.framea.y(t),body2.zposition)body2.shape.R(t)=arrayliteral([33],cos(body2.phi(t)),sin(body2.phi(t)),0,sin(body2.phi(t)),cos(body2.phi(t)),0,0,0,1)body2.shape.rshape(t)=[000]body2.shape.lengthdirection(t)=[001]body2.shape.widthdirection(t)=[100]body2.shape.length(t)=2body2.radiusbody2.shape.width(t)=2body2.radiusbody2.shape.height(t)=2body2.radiusabspos_sensor.x(t)=abspos_sensor.pos.x(t)abspos_sensor.y(t)=abspos_sensor.pos.y(t)abspos_sensor.phi(t)=abspos_sensor.pos.phi(t)connect(framea,pos+framea)abspos_sensor.pos.frame_a.fx(t)=0abspos_sensor.pos.frame_a.fy(t)=0abspos_sensor.pos.frame_a.tau(t)=0arrayliteral([3],abspos_sensor.pos.x(t),abspos_sensor.pos.y(t),abspos_sensor.pos.phi(t))=abspos_sensor.pos.r(t)abspos_sensor.pos.r(t)=arrayliteral([3],abspos_sensor.pos.frame_a.x(t),abspos_sensor.pos.frame_a.y(t),abspos_sensor.pos.frame_a.phi(t))absv_sensor.px(t)=absv_sensor.pos.x(t)absv_sensor.py(t)=absv_sensor.pos.y(t)absv_sensor.pphi(t)=absv_sensor.pos.phi(t)absv_sensor.transform.x_in(t)=dabsv_sensor.px(t)dtabsv_sensor.transform.y_in(t)=dabsv_sensor.py(t)dtabsv_sensor.transform.phi_in(t)=dabsv_sensor.pphi(t)dtabsv_sensor.v_x(t)=absv_sensor.transform.x_out(t)absv_sensor.v_y(t)=absv_sensor.transform.y_out(t)absv_sensor.w(t)=absv_sensor.transform.phi_out(t)connect(framea,pos+framea)connect(framea,transform+framea)absv_sensor.pos.frame_a.fx(t)=0absv_sensor.pos.frame_a.fy(t)=0absv_sensor.pos.frame_a.tau(t)=0arrayliteral([3],absv_sensor.pos.x(t),absv_sensor.pos.y(t),absv_sensor.pos.phi(t))=absv_sensor.pos.r(t)absv_sensor.pos.r(t)=arrayliteral([3],absv_sensor.pos.frame_a.x(t),absv_sensor.pos.frame_a.y(t),absv_sensor.pos.frame_a.phi(t))absv_sensor.transform.frame_a.fx(t)=0absv_sensor.transform.frame_a.fy(t)=0absv_sensor.transform.frame_a.tau(t)=0absv_sensor.transform.x_out(t)=absv_sensor.transform.x_in(t)absv_sensor.transform.y_out(t)=absv_sensor.transform.y_in(t)absv_sensor.transform.phi_out(t)=absv_sensor.transform.phi_in(t)absa_sensor.px(t)=absa_sensor.pos.x(t)absa_sensor.py(t)=absa_sensor.pos.y(t)absa_sensor.pphi(t)=absa_sensor.pos.phi(t)absa_sensor.vx(t)=dabsa_sensor.px(t)dtabsa_sensor.vy(t)=dabsa_sensor.py(t)dtabsa_sensor.vphi(t)=dabsa_sensor.pphi(t)dtabsa_sensor.transform.x_in(t)=dabsa_sensor.vx(t)dtabsa_sensor.transform.y_in(t)=dabsa_sensor.vy(t)dtabsa_sensor.transform.phi_in(t)=dabsa_sensor.vphi(t)dtabsa_sensor.a_x(t)=absa_sensor.transform.x_out(t)absa_sensor.a_y(t)=absa_sensor.transform.y_out(t)absa_sensor.alpha(t)=absa_sensor.transform.phi_out(t)connect(framea,pos+framea)connect(framea,transform+framea)absa_sensor.pos.frame_a.fx(t)=0absa_sensor.pos.frame_a.fy(t)=0absa_sensor.pos.frame_a.tau(t)=0arrayliteral([3],absa_sensor.pos.x(t),absa_sensor.pos.y(t),absa_sensor.pos.phi(t))=absa_sensor.pos.r(t)absa_sensor.pos.r(t)=arrayliteral([3],absa_sensor.pos.frame_a.x(t),absa_sensor.pos.frame_a.y(t),absa_sensor.pos.frame_a.phi(t))absa_sensor.transform.frame_a.fx(t)=0absa_sensor.transform.frame_a.fy(t)=0absa_sensor.transform.frame_a.tau(t)=0absa_sensor.transform.x_out(t)=absa_sensor.transform.x_in(t)absa_sensor.transform.y_out(t)=absa_sensor.transform.y_in(t)absa_sensor.transform.phi_out(t)=absa_sensor.transform.phi_in(t)relpos_sensor1.rel_x(t)=relpos_sensor1.pos.rel_x(t)relpos_sensor1.rel_y(t)=relpos_sensor1.pos.rel_y(t)relpos_sensor1.rel_phi(t)=relpos_sensor1.pos.rel_phi(t)connect(framea,pos+framea)connect(frameb,pos+frameb)relpos_sensor1.pos.frame_a.fx(t)=0relpos_sensor1.pos.frame_a.fy(t)=0relpos_sensor1.pos.frame_a.tau(t)=0relpos_sensor1.pos.frame_b.fx(t)=0relpos_sensor1.pos.frame_b.fy(t)=0relpos_sensor1.pos.frame_b.tau(t)=0arrayliteral([3],relpos_sensor1.pos.rel_x(t),relpos_sensor1.pos.rel_y(t),relpos_sensor1.pos.rel_phi(t))=relpos_sensor1.pos.r(t)relpos_sensor1.pos.r(t)=arrayliteral([3],relpos_sensor1.pos.frame_a.x(t)+relpos_sensor1.pos.frame_b.x(t),relpos_sensor1.pos.frame_a.y(t)+relpos_sensor1.pos.frame_b.y(t),relpos_sensor1.pos.frame_b.phi(t)relpos_sensor1.pos.frame_a.phi(t))relpos_sensor2.rel_x(t)=relpos_sensor2.pos.rel_x(t)relpos_sensor2.rel_y(t)=relpos_sensor2.pos.rel_y(t)relpos_sensor2.rel_phi(t)=relpos_sensor2.pos.rel_phi(t)connect(framea,pos+framea)connect(frameb,pos+frameb)relpos_sensor2.pos.frame_a.fx(t)=0relpos_sensor2.pos.frame_a.fy(t)=0relpos_sensor2.pos.frame_a.tau(t)=0relpos_sensor2.pos.frame_b.fx(t)=0relpos_sensor2.pos.frame_b.fy(t)=0relpos_sensor2.pos.frame_b.tau(t)=0arrayliteral([3],relpos_sensor2.pos.rel_x(t),relpos_sensor2.pos.rel_y(t),relpos_sensor2.pos.rel_phi(t))=relpos_sensor2.pos.r(t)relpos_sensor2.pos.r(t)=arrayliteral([3],relpos_sensor2.pos.frame_b.x(t)relpos_sensor2.pos.frame_a.x(t),relpos_sensor2.pos.frame_b.y(t)relpos_sensor2.pos.frame_a.y(t),relpos_sensor2.pos.frame_b.phi(t)relpos_sensor2.pos.frame_a.phi(t))relv_sensor1.rpx(t)=relv_sensor1.rel_pos.rel_x(t)relv_sensor1.rpy(t)=relv_sensor1.rel_pos.rel_y(t)relv_sensor1.rpphi(t)=relv_sensor1.rel_pos.rel_phi(t)relv_sensor1.transform.x_in(t)=drelv_sensor1.rpx(t)dtrelv_sensor1.transform.y_in(t)=drelv_sensor1.rpy(t)dtrelv_sensor1.transform.phi_in(t)=drelv_sensor1.rpphi(t)dtrelv_sensor1.rel_v_x(t)=relv_sensor1.transform.x_out(t)relv_sensor1.rel_v_y(t)=relv_sensor1.transform.y_out(t)relv_sensor1.rel_w(t)=relv_sensor1.transform.phi_out(t)connect(framea,relpos+frame_a)connect(frameb,relpos+frame_b)connect(framea,transform+framea)connect(frameb,transform+frameb)relv_sensor1.rel_pos.rel_x(t)=relv_sensor1.rel_pos.pos.rel_x(t)relv_sensor1.rel_pos.rel_y(t)=relv_sensor1.rel_pos.pos.rel_y(t)relv_sensor1.rel_pos.rel_phi(t)=relv_sensor1.rel_pos.pos.rel_phi(t)connect(framea,pos+framea)connect(frameb,pos+frameb)relv_sensor1.rel_pos.pos.frame_a.fx(t)=0relv_sensor1.rel_pos.pos.frame_a.fy(t)=0relv_sensor1.rel_pos.pos.frame_a.tau(t)=0relv_sensor1.rel_pos.pos.frame_b.fx(t)=0relv_sensor1.rel_pos.pos.frame_b.fy(t)=0relv_sensor1.rel_pos.pos.frame_b.tau(t)=0arrayliteral([3],relv_sensor1.rel_pos.pos.rel_x(t),relv_sensor1.rel_pos.pos.rel_y(t),relv_sensor1.rel_pos.pos.rel_phi(t))=relv_sensor1.rel_pos.pos.r(t)relv_sensor1.rel_pos.pos.rotation_matrix(t)=arrayliteral([33],cos(relv_sensor1.rel_pos.pos.frame_a.phi(t)),sin(relv_sensor1.rel_pos.pos.frame_a.phi(t)),0,sin(relv_sensor1.rel_pos.pos.frame_a.phi(t)),cos(relv_sensor1.rel_pos.pos.frame_a.phi(t)),0,0,0,1)relv_sensor1.rel_pos.pos.r(t)=transpose(relv_sensor1.rel_pos.pos.rotation_matrix(t))arrayliteral([3],relv_sensor1.rel_pos.pos.frame_b.x(t)relv_sensor1.rel_pos.pos.frame_a.x(t),relv_sensor1.rel_pos.pos.frame_a.y(t)+relv_sensor1.rel_pos.pos.frame_b.y(t),relv_sensor1.rel_pos.pos.frame_a.phi(t)+relv_sensor1.rel_pos.pos.frame_b.phi(t))relv_sensor1.transform.frame_a.fx(t)=0relv_sensor1.transform.frame_a.fy(t)=0relv_sensor1.transform.frame_a.tau(t)=0relv_sensor1.transform.frame_b.fx(t)=0relv_sensor1.transform.frame_b.fy(t)=0relv_sensor1.transform.frame_b.tau(t)=0relv_sensor1.transform.r_in(t)=arrayliteral([3],relv_sensor1.transform.x_in(t),relv_sensor1.transform.y_in(t),relv_sensor1.transform.phi_in(t))relv_sensor1.transform.R1(t)=arrayliteral([33],cos(relv_sensor1.transform.frame_a.phi(t)),sin(relv_sensor1.transform.frame_a.phi(t)),0,sin(relv_sensor1.transform.frame_a.phi(t)),cos(relv_sensor1.transform.frame_a.phi(t)),0,0,0,1)relv_sensor1.transform.rotation_matrix(t)=[100010001]relv_sensor1.transform.r_out(t)=relv_sensor1.transform.R1(t)relv_sensor1.transform.r_in(t)arrayliteral([3],relv_sensor1.transform.x_out(t),relv_sensor1.transform.y_out(t),relv_sensor1.transform.phi_out(t))=relv_sensor1.transform.r_out(t)relv_sensor2.rpx(t)=relv_sensor2.rel_pos.rel_x(t)relv_sensor2.rpy(t)=relv_sensor2.rel_pos.rel_y(t)relv_sensor2.rpphi(t)=relv_sensor2.rel_pos.rel_phi(t)relv_sensor2.transform.x_in(t)=drelv_sensor2.rpx(t)dtrelv_sensor2.transform.y_in(t)=drelv_sensor2.rpy(t)dtrelv_sensor2.transform.phi_in(t)=drelv_sensor2.rpphi(t)dtrelv_sensor2.rel_v_x(t)=relv_sensor2.transform.x_out(t)relv_sensor2.rel_v_y(t)=relv_sensor2.transform.y_out(t)relv_sensor2.rel_w(t)=relv_sensor2.transform.phi_out(t)connect(framea,relpos+frame_a)connect(frameb,relpos+frame_b)connect(framea,transform+framea)connect(frameb,transform+frameb)relv_sensor2.rel_pos.rel_x(t)=relv_sensor2.rel_pos.pos.rel_x(t)relv_sensor2.rel_pos.rel_y(t)=relv_sensor2.rel_pos.pos.rel_y(t)relv_sensor2.rel_pos.rel_phi(t)=relv_sensor2.rel_pos.pos.rel_phi(t)connect(framea,pos+framea)connect(frameb,pos+frameb)relv_sensor2.rel_pos.pos.frame_a.fx(t)=0relv_sensor2.rel_pos.pos.frame_a.fy(t)=0relv_sensor2.rel_pos.pos.frame_a.tau(t)=0relv_sensor2.rel_pos.pos.frame_b.fx(t)=0relv_sensor2.rel_pos.pos.frame_b.fy(t)=0relv_sensor2.rel_pos.pos.frame_b.tau(t)=0arrayliteral([3],relv_sensor2.rel_pos.pos.rel_x(t),relv_sensor2.rel_pos.pos.rel_y(t),relv_sensor2.rel_pos.pos.rel_phi(t))=relv_sensor2.rel_pos.pos.r(t)relv_sensor2.rel_pos.pos.rotation_matrix(t)=arrayliteral([33],cos(relv_sensor2.rel_pos.pos.frame_a.phi(t)),sin(relv_sensor2.rel_pos.pos.frame_a.phi(t)),0,sin(relv_sensor2.rel_pos.pos.frame_a.phi(t)),cos(relv_sensor2.rel_pos.pos.frame_a.phi(t)),0,0,0,1)relv_sensor2.rel_pos.pos.r(t)=transpose(relv_sensor2.rel_pos.pos.rotation_matrix(t))arrayliteral([3],relv_sensor2.rel_pos.pos.frame_a.x(t)+relv_sensor2.rel_pos.pos.frame_b.x(t),relv_sensor2.rel_pos.pos.frame_b.y(t)relv_sensor2.rel_pos.pos.frame_a.y(t),relv_sensor2.rel_pos.pos.frame_b.phi(t)relv_sensor2.rel_pos.pos.frame_a.phi(t))relv_sensor2.transform.frame_a.fx(t)=0relv_sensor2.transform.frame_a.fy(t)=0relv_sensor2.transform.frame_a.tau(t)=0relv_sensor2.transform.frame_b.fx(t)=0relv_sensor2.transform.frame_b.fy(t)=0relv_sensor2.transform.frame_b.tau(t)=0relv_sensor2.transform.r_in(t)=arrayliteral([3],relv_sensor2.transform.x_in(t),relv_sensor2.transform.y_in(t),relv_sensor2.transform.phi_in(t))relv_sensor2.transform.R1(t)=arrayliteral([33],cos(relv_sensor2.transform.frame_a.phi(t)),sin(relv_sensor2.transform.frame_a.phi(t)),0,sin(relv_sensor2.transform.frame_a.phi(t)),cos(relv_sensor2.transform.frame_a.phi(t)),0,0,0,1)relv_sensor2.transform.rotation_matrix(t)=[100010001]relv_sensor2.transform.r_out(t)=relv_sensor2.transform.R1(t)relv_sensor2.transform.r_in(t)arrayliteral([3],relv_sensor2.transform.x_out(t),relv_sensor2.transform.y_out(t),relv_sensor2.transform.phi_out(t))=relv_sensor2.transform.r_out(t)rela_sensor1.rpx(t)=rela_sensor1.rel_pos.rel_x(t)rela_sensor1.rpy(t)=rela_sensor1.rel_pos.rel_y(t)rela_sensor1.rpphi(t)=rela_sensor1.rel_pos.rel_phi(t)rela_sensor1.vrpx(t)=drela_sensor1.rpx(t)dtrela_sensor1.vrpy(t)=drela_sensor1.rpy(t)dtrela_sensor1.vrpphi(t)=drela_sensor1.rpphi(t)dtrela_sensor1.transform.x_in(t)=drela_sensor1.vrpx(t)dtrela_sensor1.transform.y_in(t)=drela_sensor1.vrpy(t)dtrela_sensor1.transform.phi_in(t)=drela_sensor1.vrpphi(t)dtrela_sensor1.rel_a_x(t)=rela_sensor1.transform.x_out(t)rela_sensor1.rel_a_y(t)=rela_sensor1.transform.y_out(t)rela_sensor1.rel_alpha(t)=rela_sensor1.transform.phi_out(t)connect(framea,relpos+frame_a)connect(frameb,relpos+frame_b)connect(framea,transform+framea)connect(frameb,transform+frameb)rela_sensor1.rel_pos.rel_x(t)=rela_sensor1.rel_pos.pos.rel_x(t)rela_sensor1.rel_pos.rel_y(t)=rela_sensor1.rel_pos.pos.rel_y(t)rela_sensor1.rel_pos.rel_phi(t)=rela_sensor1.rel_pos.pos.rel_phi(t)connect(framea,pos+framea)connect(frameb,pos+frameb)rela_sensor1.rel_pos.pos.frame_a.fx(t)=0rela_sensor1.rel_pos.pos.frame_a.fy(t)=0rela_sensor1.rel_pos.pos.frame_a.tau(t)=0rela_sensor1.rel_pos.pos.frame_b.fx(t)=0rela_sensor1.rel_pos.pos.frame_b.fy(t)=0rela_sensor1.rel_pos.pos.frame_b.tau(t)=0arrayliteral([3],rela_sensor1.rel_pos.pos.rel_x(t),rela_sensor1.rel_pos.pos.rel_y(t),rela_sensor1.rel_pos.pos.rel_phi(t))=rela_sensor1.rel_pos.pos.r(t)rela_sensor1.rel_pos.pos.rotation_matrix(t)=arrayliteral([33],cos(rela_sensor1.rel_pos.pos.frame_a.phi(t)),sin(rela_sensor1.rel_pos.pos.frame_a.phi(t)),0,sin(rela_sensor1.rel_pos.pos.frame_a.phi(t)),cos(rela_sensor1.rel_pos.pos.frame_a.phi(t)),0,0,0,1)rela_sensor1.rel_pos.pos.r(t)=transpose(rela_sensor1.rel_pos.pos.rotation_matrix(t))arrayliteral([3],rela_sensor1.rel_pos.pos.frame_b.x(t)rela_sensor1.rel_pos.pos.frame_a.x(t),rela_sensor1.rel_pos.pos.frame_b.y(t)rela_sensor1.rel_pos.pos.frame_a.y(t),rela_sensor1.rel_pos.pos.frame_b.phi(t)rela_sensor1.rel_pos.pos.frame_a.phi(t))rela_sensor1.transform.frame_a.fx(t)=0rela_sensor1.transform.frame_a.fy(t)=0rela_sensor1.transform.frame_a.tau(t)=0rela_sensor1.transform.frame_b.fx(t)=0rela_sensor1.transform.frame_b.fy(t)=0rela_sensor1.transform.frame_b.tau(t)=0rela_sensor1.transform.r_in(t)=arrayliteral([3],rela_sensor1.transform.x_in(t),rela_sensor1.transform.y_in(t),rela_sensor1.transform.phi_in(t))rela_sensor1.transform.R1(t)=arrayliteral([33],cos(rela_sensor1.transform.frame_a.phi(t)),sin(rela_sensor1.transform.frame_a.phi(t)),0,sin(rela_sensor1.transform.frame_a.phi(t)),cos(rela_sensor1.transform.frame_a.phi(t)),0,0,0,1)rela_sensor1.transform.rotation_matrix(t)=[100010001]rela_sensor1.transform.r_out(t)=rela_sensor1.transform.R1(t)rela_sensor1.transform.r_in(t)arrayliteral([3],rela_sensor1.transform.x_out(t),rela_sensor1.transform.y_out(t),rela_sensor1.transform.phi_out(t))=rela_sensor1.transform.r_out(t)rela_sensor2.rpx(t)=rela_sensor2.rel_pos.rel_x(t)rela_sensor2.rpy(t)=rela_sensor2.rel_pos.rel_y(t)rela_sensor2.rpphi(t)=rela_sensor2.rel_pos.rel_phi(t)rela_sensor2.vrpx(t)=drela_sensor2.rpx(t)dtrela_sensor2.vrpy(t)=drela_sensor2.rpy(t)dtrela_sensor2.vrpphi(t)=drela_sensor2.rpphi(t)dtrela_sensor2.transform.x_in(t)=drela_sensor2.vrpx(t)dtrela_sensor2.transform.y_in(t)=drela_sensor2.vrpy(t)dtrela_sensor2.transform.phi_in(t)=drela_sensor2.vrpphi(t)dtrela_sensor2.rel_a_x(t)=rela_sensor2.transform.x_out(t)rela_sensor2.rel_a_y(t)=rela_sensor2.transform.y_out(t)rela_sensor2.rel_alpha(t)=rela_sensor2.transform.phi_out(t)connect(framea,relpos+frame_a)connect(frameb,relpos+frame_b)connect(framea,transform+framea)connect(frameb,transform+frameb)rela_sensor2.rel_pos.rel_x(t)=rela_sensor2.rel_pos.pos.rel_x(t)rela_sensor2.rel_pos.rel_y(t)=rela_sensor2.rel_pos.pos.rel_y(t)rela_sensor2.rel_pos.rel_phi(t)=rela_sensor2.rel_pos.pos.rel_phi(t)connect(framea,pos+framea)connect(frameb,pos+frameb)rela_sensor2.rel_pos.pos.frame_a.fx(t)=0rela_sensor2.rel_pos.pos.frame_a.fy(t)=0rela_sensor2.rel_pos.pos.frame_a.tau(t)=0rela_sensor2.rel_pos.pos.frame_b.fx(t)=0rela_sensor2.rel_pos.pos.frame_b.fy(t)=0rela_sensor2.rel_pos.pos.frame_b.tau(t)=0arrayliteral([3],rela_sensor2.rel_pos.pos.rel_x(t),rela_sensor2.rel_pos.pos.rel_y(t),rela_sensor2.rel_pos.pos.rel_phi(t))=rela_sensor2.rel_pos.pos.r(t)rela_sensor2.rel_pos.pos.rotation_matrix(t)=arrayliteral([33],cos(rela_sensor2.rel_pos.pos.frame_a.phi(t)),sin(rela_sensor2.rel_pos.pos.frame_a.phi(t)),0,sin(rela_sensor2.rel_pos.pos.frame_a.phi(t)),cos(rela_sensor2.rel_pos.pos.frame_a.phi(t)),0,0,0,1)rela_sensor2.rel_pos.pos.r(t)=transpose(rela_sensor2.rel_pos.pos.rotation_matrix(t))arrayliteral([3],rela_sensor2.rel_pos.pos.frame_b.x(t)rela_sensor2.rel_pos.pos.frame_a.x(t),rela_sensor2.rel_pos.pos.frame_a.y(t)+rela_sensor2.rel_pos.pos.frame_b.y(t),rela_sensor2.rel_pos.pos.frame_a.phi(t)+rela_sensor2.rel_pos.pos.frame_b.phi(t))rela_sensor2.transform.frame_a.fx(t)=0rela_sensor2.transform.frame_a.fy(t)=0rela_sensor2.transform.frame_a.tau(t)=0rela_sensor2.transform.frame_b.fx(t)=0rela_sensor2.transform.frame_b.fy(t)=0rela_sensor2.transform.frame_b.tau(t)=0rela_sensor2.transform.r_in(t)=arrayliteral([3],rela_sensor2.transform.x_in(t),rela_sensor2.transform.y_in(t),rela_sensor2.transform.phi_in(t))rela_sensor2.transform.R1(t)=arrayliteral([33],cos(rela_sensor2.transform.frame_a.phi(t)),sin(rela_sensor2.transform.frame_a.phi(t)),0,sin(rela_sensor2.transform.frame_a.phi(t)),cos(rela_sensor2.transform.frame_a.phi(t)),0,0,0,1)rela_sensor2.transform.rotation_matrix(t)=[100010001]rela_sensor2.transform.r_out(t)=rela_sensor2.transform.R1(t)rela_sensor2.transform.r_in(t)arrayliteral([3],rela_sensor2.transform.x_out(t),rela_sensor2.transform.y_out(t),rela_sensor2.transform.phi_out(t))=rela_sensor2.transform.r_out(t)distance.framea.fx(t)=0distance.framea.fy(t)=0distance.framea.tau(t)=0distance.frameb.fx(t)=0distance.frameb.fy(t)=0distance.frameb.tau(t)=0distance.L2(t)=(distance.framea.x(t)+distance.frameb.x(t))2+(distance.frameb.y(t)distance.framea.y(t))2distance.ssmall2(t)=distance.ssmall2distance.distance(t)=ifelse(distance.ssmall2(t)<distance.L2(t),distance.L2(t),distance.ssmall2+distance.L2(t)2distance.ssmall)distance.arrow.r(t)=arrayliteral([3],distance.framea.x(t),distance.framea.y(t),distance.zposition)distance.arrow.R(t)=arrayliteral([33],1.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,1.0)distance.arrow.rshape(t)=[000]distance.arrow.lengthdirection(t)=arrayliteral([3],distance.framea.x(t)+distance.frameb.x(t),distance.frameb.y(t)distance.framea.y(t),0)distance.arrow.widthdirection(t)=[001]distance.arrow.length(t)=distance.distance(t)distance.arrow.width(t)=distance.arrowdiameterdistance.arrow.height(t)=distance.arrowdiameter]

Source

dyad
"""
Sensor test with two free-falling bodies: validates all 6 sensor types.

Translates the "Sensors (two free falling bodies)" test from test_PlanarMechanics.jl.
Two bodies (m=1, I=1) start at the origin with zero velocity and fall under gravity.
A fixed base sits at the origin. Three absolute sensors are attached to body1, and six
relative sensors measure pairs (body1-vs-base and body1-vs-body2).
"""
test component SensorsTest
  world = World() {
    "Dyad": {
      "placement": {
        "diagram": {"iconName": "default", "x1": 20, "y1": 615, "x2": 120, "y2": 715, "rot": 0}
      },
      "tags": []
    }
  }
  body1 = Body(m = 1.0, I = 1.0) {
    "Dyad": {
      "placement": {
        "diagram": {"iconName": "default", "x1": 312, "y1": 715, "x2": 412, "y2": 815, "rot": 0}
      },
      "tags": []
    }
  }
  body2 = Body(m = 1.0, I = 1.0) {
    "Dyad": {
      "placement": {
        "diagram": {"iconName": "default", "x1": 312, "y1": 1270, "x2": 412, "y2": 1370, "rot": 0}
      },
      "tags": []
    }
  }
  abs_pos_sensor = AbsolutePosition(resolve_in_frame = ResolveInFrame.World()) {
    "Dyad": {
      "placement": {
        "diagram": {"iconName": "default", "x1": 165, "y1": 295, "x2": 265, "y2": 395, "rot": 0}
      },
      "tags": []
    }
  }
  abs_v_sensor = AbsoluteVelocity(resolve_in_frame = ResolveInFrame.World()) {
    "Dyad": {
      "placement": {
        "diagram": {"iconName": "default", "x1": 165, "y1": 820, "x2": 265, "y2": 920, "rot": 0}
      },
      "tags": []
    }
  }
  abs_a_sensor = AbsoluteAcceleration(resolve_in_frame = ResolveInFrame.World()) {
    "Dyad": {
      "placement": {
        "diagram": {"iconName": "default", "x1": 160, "y1": 990, "x2": 260, "y2": 1090, "rot": 0}
      },
      "tags": []
    }
  }
  rel_pos_sensor1 = RelativePosition(resolve_in_frame = ResolveInFrame.World()) {
    "Dyad": {
      "placement": {
        "diagram": {
          "iconName": "default",
          "x1": 163.5,
          "y1": 415,
          "x2": 263.5,
          "y2": 515,
          "rot": 0
        }
      },
      "tags": []
    }
  }
  rel_pos_sensor2 = RelativePosition(resolve_in_frame = ResolveInFrame.World()) {
    "Dyad": {
      "placement": {
        "diagram": {"iconName": "default", "x1": 165, "y1": 1145, "x2": 265, "y2": 1245, "rot": 0}
      },
      "tags": []
    }
  }
  rel_v_sensor1 = RelativeVelocity(resolve_in_frame = ResolveInFrame.World()) {
    "Dyad": {
      "placement": {
        "diagram": {
          "iconName": "default",
          "x1": 163.5,
          "y1": 615,
          "x2": 263.5,
          "y2": 715,
          "rot": 0
        }
      },
      "tags": []
    }
  }
  rel_v_sensor2 = RelativeVelocity(resolve_in_frame = ResolveInFrame.World()) {
    "Dyad": {
      "placement": {
        "diagram": {"iconName": "default", "x1": 165, "y1": 1395, "x2": 265, "y2": 1495, "rot": 0}
      },
      "tags": []
    }
  }
  rel_a_sensor1 = RelativeAcceleration(resolve_in_frame = ResolveInFrame.World()) {
    "Dyad": {
      "placement": {
        "diagram": {"iconName": "default", "x1": 163.5, "y1": 85, "x2": 263.5, "y2": 185, "rot": 0}
      },
      "tags": []
    }
  }
  rel_a_sensor2 = RelativeAcceleration(resolve_in_frame = ResolveInFrame.World()) {
    "Dyad": {
      "placement": {
        "diagram": {"iconName": "default", "x1": 165, "y1": 1270, "x2": 265, "y2": 1370, "rot": 0}
      },
      "tags": []
    }
  }
  distance = MultibodyComponents.PlanarMechanics.Distance() {
    "Dyad": {
      "placement": {
        "diagram": {"iconName": "default", "x1": 370, "y1": 1070, "x2": 470, "y2": 1170, "rot": 0}
      },
      "tags": []
    }
  }
relations
  # initial conditions for body1
  initial body1.r = [0, 0]
  initial body1.v = [0, 0]
  initial body1.phi = 0
  initial body1.w = 0
  # initial conditions for body2
  initial body2.r = [0, 0]
  initial body2.v = [0, 0]
  initial body2.phi = 0
  initial body2.w = 0
  # absolute sensors on body1
  connect(body1.frame_a, abs_pos_sensor.frame_a) {
    "Dyad": {
      "edges": [
        {
          "S": 1,
          "M": [
            {"x": 292, "y": 765},
            {"x": 292, "y": 565},
            {"x": 145, "y": 565},
            {"x": 145, "y": 345}
          ],
          "E": 2
        }
      ],
      "renderStyle": "standard"
    }
  }
  connect(body1.frame_a, abs_v_sensor.frame_a) {
    "Dyad": {
      "edges": [
        {"S": 1, "M": [{"x": 292, "y": 765}, {"x": 292, "y": 970}], "E": -1},
        {"S": -1, "M": [{"x": 145, "y": 870}], "E": 2}
      ],
      "junctions": [{"x": 145, "y": 970}],
      "renderStyle": "standard"
    }
  }
  connect(body1.frame_a, abs_a_sensor.frame_a) {
    "Dyad": {
      "edges": [
        {
          "S": 1,
          "M": [
            {"x": 292, "y": 765},
            {"x": 292, "y": 970},
            {"x": 145, "y": 970},
            {"x": 145, "y": 1040}
          ],
          "E": 2
        }
      ],
      "renderStyle": "standard"
    }
  }
  # rel_pos_sensor1: frame_a=body1, frame_b=base
  connect(body1.frame_a, rel_pos_sensor1.frame_a) {
    "Dyad": {
      "edges": [
        {"S": 1, "M": [{"x": 292, "y": 765}], "E": -1},
        {"S": -1, "M": [{"x": 145, "y": 565}], "E": -2},
        {"S": -2, "M": [], "E": 2}
      ],
      "junctions": [{"x": 292, "y": 565}, {"x": 145, "y": 465}],
      "renderStyle": "standard"
    }
  }
  connect(world.frame_b, rel_pos_sensor1.frame_b) {
    "Dyad": {
      "edges": [
        {"S": 1, "M": [], "E": -1},
        {
          "S": -1,
          "M": [{"x": 135, "y": 20}, {"x": 302, "y": 20}, {"x": 302, "y": 465}],
          "E": 2
        }
      ],
      "junctions": [{"x": 135, "y": 665}],
      "renderStyle": "standard"
    }
  }
  # rel_pos_sensor2: frame_a=body1, frame_b=body2
  connect(body1.frame_a, rel_pos_sensor2.frame_a) {
    "Dyad": {
      "edges": [{"S": 1, "M": [{"x": 135, "y": 765}], "E": -1}, {"S": -1, "M": [], "E": 2}],
      "junctions": [{"x": 135, "y": 1195}],
      "renderStyle": "standard"
    }
  }
  connect(body2.frame_a, rel_pos_sensor2.frame_b, distance.frame_b) {
    "Dyad": {
      "edges": [
        {"S": 1, "M": [], "E": -1},
        {"S": -1, "M": [{"x": 282, "y": 1195}], "E": -2},
        {"S": -2, "M": [], "E": 2},
        {"S": 3, "M": [{"x": 500, "y": 1120}, {"x": 500, "y": 1195}], "E": -2}
      ],
      "junctions": [{"x": 282, "y": 1320}, {"x": 280, "y": 1195}],
      "renderStyle": "standard"
    }
  }
  # rel_v_sensor1: frame_a=base, frame_b=body1
  connect(world.frame_b, rel_v_sensor1.frame_a) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}], "renderStyle": "standard"}}
  connect(body1.frame_a, rel_v_sensor1.frame_b) {
    "Dyad": {
      "edges": [{"S": 1, "M": [{"x": 292, "y": 765}], "E": -1}, {"S": -1, "M": [], "E": 2}],
      "junctions": [{"x": 292, "y": 665}],
      "renderStyle": "standard"
    }
  }
  # rel_v_sensor2: frame_a=body1, frame_b=body2
  connect(body1.frame_a, rel_v_sensor2.frame_a) {
    "Dyad": {
      "edges": [{"S": 1, "M": [{"x": 135, "y": 765}, {"x": 135, "y": 1445}], "E": 2}],
      "renderStyle": "standard"
    }
  }
  connect(body2.frame_a, rel_v_sensor2.frame_b) {
    "Dyad": {
      "edges": [{"S": 1, "M": [{"x": 282, "y": 1320}, {"x": 282, "y": 1445}], "E": 2}],
      "renderStyle": "standard"
    }
  }
  # rel_a_sensor1: frame_a=body1, frame_b=base
  connect(body1.frame_a, rel_a_sensor1.frame_a) {
    "Dyad": {
      "edges": [
        {"S": 1, "M": [], "E": -1},
        {
          "S": -1,
          "M": [{"x": 292, "y": 30}, {"x": 145, "y": 30}, {"x": 145, "y": 135}],
          "E": 2
        }
      ],
      "junctions": [{"x": 292, "y": 765}],
      "renderStyle": "standard"
    }
  }
  connect(world.frame_b, rel_a_sensor1.frame_b) {
    "Dyad": {
      "edges": [
        {"S": 1, "M": [{"x": 135, "y": 665}], "E": -1},
        {"S": -1, "M": [{"x": 282, "y": 240}, {"x": 282, "y": 135}], "E": 2}
      ],
      "junctions": [{"x": 135, "y": 240}],
      "renderStyle": "standard"
    }
  }
  # rel_a_sensor2: frame_a=body1, frame_b=body2
  connect(rel_a_sensor2.frame_a, body1.frame_a, distance.frame_a) {
    "Dyad": {
      "edges": [
        {"S": -1, "M": [], "E": 1},
        {"S": 2, "M": [{"x": 135, "y": 765}], "E": -2},
        {"S": -2, "M": [], "E": -1},
        {"S": 3, "M": [], "E": -2}
      ],
      "junctions": [{"x": 135, "y": 1320}, {"x": 135, "y": 1120}],
      "renderStyle": "standard"
    }
  }
  connect(body2.frame_a, rel_a_sensor2.frame_b) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}], "renderStyle": "standard"}}
metadata {"Dyad": {"tests": {"case1": {"stop": 3}}}}
end
Flattened Source
dyad
"""
Sensor test with two free-falling bodies: validates all 6 sensor types.

Translates the "Sensors (two free falling bodies)" test from test_PlanarMechanics.jl.
Two bodies (m=1, I=1) start at the origin with zero velocity and fall under gravity.
A fixed base sits at the origin. Three absolute sensors are attached to body1, and six
relative sensors measure pairs (body1-vs-base and body1-vs-body2).
"""
test component SensorsTest
  world = World() {
    "Dyad": {
      "placement": {
        "diagram": {"iconName": "default", "x1": 20, "y1": 615, "x2": 120, "y2": 715, "rot": 0}
      },
      "tags": []
    }
  }
  body1 = Body(m = 1.0, I = 1.0) {
    "Dyad": {
      "placement": {
        "diagram": {"iconName": "default", "x1": 312, "y1": 715, "x2": 412, "y2": 815, "rot": 0}
      },
      "tags": []
    }
  }
  body2 = Body(m = 1.0, I = 1.0) {
    "Dyad": {
      "placement": {
        "diagram": {"iconName": "default", "x1": 312, "y1": 1270, "x2": 412, "y2": 1370, "rot": 0}
      },
      "tags": []
    }
  }
  abs_pos_sensor = AbsolutePosition(resolve_in_frame = ResolveInFrame.World()) {
    "Dyad": {
      "placement": {
        "diagram": {"iconName": "default", "x1": 165, "y1": 295, "x2": 265, "y2": 395, "rot": 0}
      },
      "tags": []
    }
  }
  abs_v_sensor = AbsoluteVelocity(resolve_in_frame = ResolveInFrame.World()) {
    "Dyad": {
      "placement": {
        "diagram": {"iconName": "default", "x1": 165, "y1": 820, "x2": 265, "y2": 920, "rot": 0}
      },
      "tags": []
    }
  }
  abs_a_sensor = AbsoluteAcceleration(resolve_in_frame = ResolveInFrame.World()) {
    "Dyad": {
      "placement": {
        "diagram": {"iconName": "default", "x1": 160, "y1": 990, "x2": 260, "y2": 1090, "rot": 0}
      },
      "tags": []
    }
  }
  rel_pos_sensor1 = RelativePosition(resolve_in_frame = ResolveInFrame.World()) {
    "Dyad": {
      "placement": {
        "diagram": {
          "iconName": "default",
          "x1": 163.5,
          "y1": 415,
          "x2": 263.5,
          "y2": 515,
          "rot": 0
        }
      },
      "tags": []
    }
  }
  rel_pos_sensor2 = RelativePosition(resolve_in_frame = ResolveInFrame.World()) {
    "Dyad": {
      "placement": {
        "diagram": {"iconName": "default", "x1": 165, "y1": 1145, "x2": 265, "y2": 1245, "rot": 0}
      },
      "tags": []
    }
  }
  rel_v_sensor1 = RelativeVelocity(resolve_in_frame = ResolveInFrame.World()) {
    "Dyad": {
      "placement": {
        "diagram": {
          "iconName": "default",
          "x1": 163.5,
          "y1": 615,
          "x2": 263.5,
          "y2": 715,
          "rot": 0
        }
      },
      "tags": []
    }
  }
  rel_v_sensor2 = RelativeVelocity(resolve_in_frame = ResolveInFrame.World()) {
    "Dyad": {
      "placement": {
        "diagram": {"iconName": "default", "x1": 165, "y1": 1395, "x2": 265, "y2": 1495, "rot": 0}
      },
      "tags": []
    }
  }
  rel_a_sensor1 = RelativeAcceleration(resolve_in_frame = ResolveInFrame.World()) {
    "Dyad": {
      "placement": {
        "diagram": {"iconName": "default", "x1": 163.5, "y1": 85, "x2": 263.5, "y2": 185, "rot": 0}
      },
      "tags": []
    }
  }
  rel_a_sensor2 = RelativeAcceleration(resolve_in_frame = ResolveInFrame.World()) {
    "Dyad": {
      "placement": {
        "diagram": {"iconName": "default", "x1": 165, "y1": 1270, "x2": 265, "y2": 1370, "rot": 0}
      },
      "tags": []
    }
  }
  distance = MultibodyComponents.PlanarMechanics.Distance() {
    "Dyad": {
      "placement": {
        "diagram": {"iconName": "default", "x1": 370, "y1": 1070, "x2": 470, "y2": 1170, "rot": 0}
      },
      "tags": []
    }
  }
relations
  # initial conditions for body1
  initial body1.r = [0, 0]
  initial body1.v = [0, 0]
  initial body1.phi = 0
  initial body1.w = 0
  # initial conditions for body2
  initial body2.r = [0, 0]
  initial body2.v = [0, 0]
  initial body2.phi = 0
  initial body2.w = 0
  # absolute sensors on body1
  connect(body1.frame_a, abs_pos_sensor.frame_a) {
    "Dyad": {
      "edges": [
        {
          "S": 1,
          "M": [
            {"x": 292, "y": 765},
            {"x": 292, "y": 565},
            {"x": 145, "y": 565},
            {"x": 145, "y": 345}
          ],
          "E": 2
        }
      ],
      "renderStyle": "standard"
    }
  }
  connect(body1.frame_a, abs_v_sensor.frame_a) {
    "Dyad": {
      "edges": [
        {"S": 1, "M": [{"x": 292, "y": 765}, {"x": 292, "y": 970}], "E": -1},
        {"S": -1, "M": [{"x": 145, "y": 870}], "E": 2}
      ],
      "junctions": [{"x": 145, "y": 970}],
      "renderStyle": "standard"
    }
  }
  connect(body1.frame_a, abs_a_sensor.frame_a) {
    "Dyad": {
      "edges": [
        {
          "S": 1,
          "M": [
            {"x": 292, "y": 765},
            {"x": 292, "y": 970},
            {"x": 145, "y": 970},
            {"x": 145, "y": 1040}
          ],
          "E": 2
        }
      ],
      "renderStyle": "standard"
    }
  }
  # rel_pos_sensor1: frame_a=body1, frame_b=base
  connect(body1.frame_a, rel_pos_sensor1.frame_a) {
    "Dyad": {
      "edges": [
        {"S": 1, "M": [{"x": 292, "y": 765}], "E": -1},
        {"S": -1, "M": [{"x": 145, "y": 565}], "E": -2},
        {"S": -2, "M": [], "E": 2}
      ],
      "junctions": [{"x": 292, "y": 565}, {"x": 145, "y": 465}],
      "renderStyle": "standard"
    }
  }
  connect(world.frame_b, rel_pos_sensor1.frame_b) {
    "Dyad": {
      "edges": [
        {"S": 1, "M": [], "E": -1},
        {
          "S": -1,
          "M": [{"x": 135, "y": 20}, {"x": 302, "y": 20}, {"x": 302, "y": 465}],
          "E": 2
        }
      ],
      "junctions": [{"x": 135, "y": 665}],
      "renderStyle": "standard"
    }
  }
  # rel_pos_sensor2: frame_a=body1, frame_b=body2
  connect(body1.frame_a, rel_pos_sensor2.frame_a) {
    "Dyad": {
      "edges": [{"S": 1, "M": [{"x": 135, "y": 765}], "E": -1}, {"S": -1, "M": [], "E": 2}],
      "junctions": [{"x": 135, "y": 1195}],
      "renderStyle": "standard"
    }
  }
  connect(body2.frame_a, rel_pos_sensor2.frame_b, distance.frame_b) {
    "Dyad": {
      "edges": [
        {"S": 1, "M": [], "E": -1},
        {"S": -1, "M": [{"x": 282, "y": 1195}], "E": -2},
        {"S": -2, "M": [], "E": 2},
        {"S": 3, "M": [{"x": 500, "y": 1120}, {"x": 500, "y": 1195}], "E": -2}
      ],
      "junctions": [{"x": 282, "y": 1320}, {"x": 280, "y": 1195}],
      "renderStyle": "standard"
    }
  }
  # rel_v_sensor1: frame_a=base, frame_b=body1
  connect(world.frame_b, rel_v_sensor1.frame_a) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}], "renderStyle": "standard"}}
  connect(body1.frame_a, rel_v_sensor1.frame_b) {
    "Dyad": {
      "edges": [{"S": 1, "M": [{"x": 292, "y": 765}], "E": -1}, {"S": -1, "M": [], "E": 2}],
      "junctions": [{"x": 292, "y": 665}],
      "renderStyle": "standard"
    }
  }
  # rel_v_sensor2: frame_a=body1, frame_b=body2
  connect(body1.frame_a, rel_v_sensor2.frame_a) {
    "Dyad": {
      "edges": [{"S": 1, "M": [{"x": 135, "y": 765}, {"x": 135, "y": 1445}], "E": 2}],
      "renderStyle": "standard"
    }
  }
  connect(body2.frame_a, rel_v_sensor2.frame_b) {
    "Dyad": {
      "edges": [{"S": 1, "M": [{"x": 282, "y": 1320}, {"x": 282, "y": 1445}], "E": 2}],
      "renderStyle": "standard"
    }
  }
  # rel_a_sensor1: frame_a=body1, frame_b=base
  connect(body1.frame_a, rel_a_sensor1.frame_a) {
    "Dyad": {
      "edges": [
        {"S": 1, "M": [], "E": -1},
        {
          "S": -1,
          "M": [{"x": 292, "y": 30}, {"x": 145, "y": 30}, {"x": 145, "y": 135}],
          "E": 2
        }
      ],
      "junctions": [{"x": 292, "y": 765}],
      "renderStyle": "standard"
    }
  }
  connect(world.frame_b, rel_a_sensor1.frame_b) {
    "Dyad": {
      "edges": [
        {"S": 1, "M": [{"x": 135, "y": 665}], "E": -1},
        {"S": -1, "M": [{"x": 282, "y": 240}, {"x": 282, "y": 135}], "E": 2}
      ],
      "junctions": [{"x": 135, "y": 240}],
      "renderStyle": "standard"
    }
  }
  # rel_a_sensor2: frame_a=body1, frame_b=body2
  connect(rel_a_sensor2.frame_a, body1.frame_a, distance.frame_a) {
    "Dyad": {
      "edges": [
        {"S": -1, "M": [], "E": 1},
        {"S": 2, "M": [{"x": 135, "y": 765}], "E": -2},
        {"S": -2, "M": [], "E": -1},
        {"S": 3, "M": [], "E": -2}
      ],
      "junctions": [{"x": 135, "y": 1320}, {"x": 135, "y": 1120}],
      "renderStyle": "standard"
    }
  }
  connect(body2.frame_a, rel_a_sensor2.frame_b) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}], "renderStyle": "standard"}}
metadata {"Dyad": {"tests": {"case1": {"stop": 3}}}}
end


Test Cases

Test Case case1