Suitcase Robot Model

The suitcase robot model simulates a testbed for mounting actuation inside a suitcase. It corresponds closely to the physical prototype. It is intended as a basis for exploring hardware to add into the suitcase.

This model is demonstrated in the suitcase-demo.wbt world.

This model makes use of several objects defined in proto files: suitcase.proto, pedestal.proto, and ball_array.proto. These make use of embedded Lua scripting to parametrically generate world objects.

../_images/suitcase-demo2.png

Screenshot of Webots model of actuated suitcase sitting on a gallery pedestal.

Sample Control Code

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
# suitcase.py
#
# Sample Webots controller file for driving the four-motor suitcase actuator insert.
# No copyright, 2021, Garth Zeglin.  This file is explicitly placed in the public domain.

print("loading suitcase.py...")

# Standard Python imports.
import math, random

# Import the Webots simulator API.
from controller import Robot

# Define the time step in milliseconds between controller updates.
EVENT_LOOP_DT = 200

################################################################

# The sample controller is defined as an class which is then instanced as a
# singleton control object.  This is conventional Python practice and also
# simplifies the implementation of the Arduino interface which connects this
# code to physical hardware.

class Suitcase(Robot):
    def __init__(self):

        # Initialize the superclass which implements the Robot API.
        super().__init__()
        
        robot_name = self.getName()
        print("%s: controller connected." % (robot_name))

        # Fetch handle for the four stepper motors.
        j1 = self.getDevice('motor1')
        j2 = self.getDevice('motor2')
        j3 = self.getDevice('motor3')
        j4 = self.getDevice('motor4')

        # Convenience list of all actuators.
        self.motors = [j1, j2, j3, j4]

        # Configure the motors for velocity control by setting
        # the position targets to infinity.
        for j in self.motors:
            j.setPosition(float('inf'))
            j.setVelocity(0)

        return

    def run(self):
        # Run loop to execute a periodic script until the simulation quits.
        # If the controller returns -1, the simulator is quitting.

        # Time until next control event in milliseconds.
        event_timer = 0
        state_index = 'rest'
        
        while self.step(EVENT_LOOP_DT) != -1:
            # Read simulator clock time.
            t = self.getTime()

            # Change the target velocity in a cycle with a two-second period.
            event_timer -= EVENT_LOOP_DT
            if event_timer < 0:

                if state_index == 'rest':
                    state_index = 'moving'
                    event_timer += 1500
                    for j in self.motors:
                        vel = math.pi * (1 - 2*random.random())
                        j.setVelocity(vel)

                else:
                    state_index = 'rest'
                    event_timer += 500
                    for j in self.motors:
                        j.setVelocity(0)

                print(f"Switched to state {state_index}")

################################################################
# If running directly from Webots as a script, the following will begin execution.
# This will have no effect when this file is imported as a module.
if __name__ == "__main__":
    robot = Suitcase()
    robot.run()