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