Proxy Robot Model

The proxy robot model is a simplification of the wobbly two-wheeled robot intended for displaying the position of a remote robot using the delegate robot model. The body has no actuators, sensors, or physics. It does participate in collisions, acting like a fixed rigid body.

This model is demonstrated in the network-party.wbt world.

../_images/proxy-sim.jpg

Screenshot of Webots model of a diff-drive ‘proxy’ robot.

proxy.proto

The robot model has been encapsulated in a .proto file for easy reuse. The model includes user-accessible scaling and color parameters.

  1#VRML_SIM R2023b utf8
  2# Proxy robot body to represent a remote robot, based on the wobbly robot body.
  3# This robot has no physics but is positioned by a delegate in response to
  4# position data reported over the network.
  5# documentation url: https://courses.ideate.cmu.edu/16-375
  6# license: No copyright, 2020-2026 Garth Zeglin.  This file is explicitly placed in the public domain.
  7# template language: javascript
  8
  9PROTO proxy [
 10  field SFVec3f    translation  0 0 0
 11  field SFRotation rotation     0 1 0 0
 12  field SFString   controller   ""
 13  field SFString   name         "proxy"
 14  field SFFloat    wheelRadius  0.1
 15  field SFFloat    axleLength   0.14
 16  field SFColor    bodyColor    0.8 0.8 0.8
 17  field SFColor    wheelColor   0.3 0.3 0.3
 18  field SFString   customData   ""
 19]
 20{
 21  Robot {
 22    # connect properties to user-visible data fields
 23    translation IS translation
 24    rotation IS rotation
 25    controller IS controller
 26    name IS name
 27    customData IS customData
 28
 29    # calculate derived parameters
 30    %<
 31      let counterweightHeight = fields.wheelRadius.value;
 32      let counterweightOffset = 0.75*fields.wheelRadius.value;
 33      let counterweightTop    = 1.25*fields.wheelRadius.value;
 34      let sensorHeight        = 3*fields.wheelRadius.value;
 35      let stalkHeight         = sensorHeight - counterweightTop;
 36      let stalkOffset         = counterweightTop + 0.5*stalkHeight;
 37    >%
 38
 39    children [
 40      # The body group contains three cylinders: the massive counterweight at
 41      # bottom, a thin stalk rising above it, topped by the sensor disc.
 42      # All these shapes participate in collision; the axle is kept separate
 43      # as it is just for rendering.
 44      DEF bodyShape Group {
 45        children [
 46          # counterweight
 47          Transform {
 48            translation 0 0 %<= counterweightOffset >%
 49            rotation 1 0 0 0
 50            children [
 51              Shape {
 52                appearance DEF bodyAppearance PBRAppearance {
 53                  baseColor IS bodyColor
 54                  roughness 0.5
 55                  metalness 0.5
 56                }
 57
 58                geometry Cylinder {
 59                  height %<= counterweightHeight >%
 60                  radius 0.05
 61                }
 62              }
 63            ]
 64          }
 65  	  # sensor disc
 66          Transform {
 67            translation 0 0 %<= sensorHeight >%
 68            rotation 1 0 0 0
 69            children [
 70              Shape {
 71                appearance USE bodyAppearance
 72                geometry Cylinder {
 73                  height 0.01
 74                  radius 0.025
 75                }
 76              }
 77            ]
 78          }
 79	  # stalk
 80          Transform {
 81            translation 0 0 %<= stalkOffset >%
 82            rotation 1 0 0 0
 83            children [
 84              Shape {
 85                appearance USE bodyAppearance
 86                geometry Cylinder {
 87                  height %<= stalkHeight >%
 88                  radius 0.01
 89                }
 90              }
 91            ]
 92          }
 93        ]
 94      }
 95      # Visible axle shape, not part of the boundingObject.
 96      DEF axleShape Transform {
 97        translation 0 0 %<= fields.wheelRadius.value >%
 98        rotation 1 0 0 1.5707963267948966
 99        children [
100          Shape {
101            appearance USE bodyAppearance
102            geometry Cylinder {
103              height %<= fields.axleLength.value + 0.02 >%
104              radius 0.005
105            }
106          }
107        ]
108      }
109      # Define the left wheel axis, pointing in the +Y direction along the axle.
110      HingeJoint {
111        jointParameters HingeJointParameters {
112          axis 0 1 0
113          anchor 0 0 %<= fields.wheelRadius.value >%
114        }
115	# Define the left wheel solid, offset along +Y along the axle.
116        endPoint DEF leftWheel Solid {
117          translation 0 %<= 0.5*fields.axleLength.value >% %<= fields.wheelRadius.value >%
118          rotation -1 0 0 1.5707963267948966
119          children [
120            # Define the left wheel shape and appearance, which is used by the right wheel solid.
121            DEF wheelShape Transform {
122              rotation 0 0 1 0
123              children [
124                Shape {
125                  appearance PBRAppearance {
126                    baseColor IS wheelColor
127                    roughness 0.5
128                    metalness 0.5
129                  }
130                  geometry Cylinder {
131                    height 0.01
132                    radius %<= fields.wheelRadius.value >%
133                  }
134                }
135              ]
136            }
137          ]
138          name "left wheel"
139          boundingObject USE wheelShape
140        }
141      }
142      # Define the right wheel axis, also pointing in the +Y direction along the axle
143      # so positive wheel rotations will move forward.
144      HingeJoint {
145        jointParameters HingeJointParameters {
146          axis 0 1 0
147          anchor 0 0 %<= fields.wheelRadius.value >%
148        }
149	# Define the right wheel solid, offset along -Y along the axle.
150	# The wheel shape is inherited from the left wheel.
151        endPoint DEF rightWheel Solid {
152          translation 0 %<= -0.5*fields.axleLength.value >% %<= fields.wheelRadius.value >%
153          rotation 1 0 0 1.5707963267948966
154          children [
155            USE wheelShape
156          ]
157          name "right wheel"
158          boundingObject USE wheelShape
159        }
160      }
161    ] # close children list of Robot
162    boundingObject USE bodyShape
163  } # close Robot
164}