Rodney Dunning's Home Page | Research and Scholarship | VPython | Clock Synchronization


Introduction

In special relativity, it is important to specify how the clocks in a given reference frame are synchronized. This animation gives the user two methods for synchronizing the clocks in his reference frame, one of which works and one doesn't.

Description

The Master Clock is located at the center of the animation window, and is surrounded by eight clocks in two "+"-pattern arrangements. The clocks of the first group are all 50 light-seconds from the Master Clock, while the clocks of the second group are all 100 light-seconds from the Master Clock. At t = 10.0 seconds, the Master Clock sends a "set signal" to all the other clocks. The set signal contains a time stamp that reads 10.0 seconds.

The other clocks in the reference frame can be set in one of two ways, as determined by the user. In Method 1, each clock simply sets to the time recorded in the time stamp, viz., 10.0 seconds. In Method 2, each clock sets itself to the time recorded in the time stamp, but adds an additional number of seconds equal to its distance from the Master Clock (in seconds).

Each clock is represented by a text box that shows either its current reading, or its distance from the Master Clock in light seconds. The set signal is a ring that radiates out from the Master Clock.

Screen Shots

The time stamp signal has passed the first group of clocks
The first method of clock synchronization. The light signal from the Master Clock has reached the first group of clocks. Each clock has set itself to the time stamp in the signal.

The time stamp signal has reached the second group of clocks
The second method of clock synchronization. The light signal from the Master Clock has reached the second groups of clocks. Each clock has set itself to the time stamp in the signal, plus an additional number of seconds each to the separation distance (in seconds) between itself and the Master Clock.

Suggested Use

I had success with the following steps in my modern physics class:

  1. I describe the first synchronization method, and then ask the students if it work. (Most say it will.)
  2. I run the animation selecting Method 1 at the prompt. The students see that the method fails to correctly synchronize the clocks.
  3. I ask the students what changes or additional directions are needed in the synchronization procedure. I guide them to articulate on their own the basic steps of the second method.
  4. I run the animation, selecting Method 2 at the prompt. The students see that the method works.

Hints:

Source Code

The source code appears between the bars below. Copy and paste the code into the Python IDLE environment, and hit F5 to run the code.


from visual import *
from __future__ import division

"""
    Rodney Dunning
    Assistant Professor of Physics
    Longwood University

    An illustration of clock
    synchronization.

"""

#--------------------------------------
# Determine the setting method, from
# user input.
#

print "How do you want to set the clocks?"
print "\n"
print "The Master Clock sends a set signal that contains"
print "a time stamp indicating the reading on the Master"
print "Clock when the set signal was sent."
print "\n"
print "In this animation, the set signal is sent at"
print "t = 10 seconds."
print "\n"
print "Method 1: When a clock receives the set signal"
print "          from the Master Clock, that clock is"
print "          set to match the time stamp in the signal."
print "\n"
print "Method 2: When a clock receives the set signal"
print "          from the Master Clock, that clock is"
print "          set to the time stamp in the signal"
print "          plus the separation distance (in seconds)"
print "          between that clock and the Master Clock."
print "\n"

finished = 0
while not finished:
    set_method = input("Choose Method 1 [Enter 1]"
                       "or Method 2 [Enter 2]: ")

    finished = set_method == 1 or set_method == 2

    if(not finished): print "Please try again.\n\n"

# Next line allows us to use set_method in a formula
# for the set time of each clock:

set_method -= 1

#--------------------------------------
# Scene definitions and functions

scene.title = "Clock Synchronization"
scene.x = 0
scene.y = 0
scene.width = 800
scene.height = 600
scene.range = (150,150,150)
scene.autoscale = 0 ##0 means autoscaling is OFF
scene.userzoom = 1 ##0 means user cannot zoom
scene.userspin = 0 ##0 means user cannot spin
scene.lights = [vector(0,0,1)]
scene.ambient = 0.5
scene.label = label(visible=0,
                    pos=(0,0,0),
                    xoffset = 0,
                    yoffset = 0,
                    text = ("Clock synchronization. Click to\n"
                            "begin.\n"))

def check_for_pause(scene): #checks for pause request
    if scene.mouse.clicked:
        scene.mouse.getclick()
        pause(scene)

def pause(scene): #pauses the animation
    while 1:
        if scene.mouse.clicked:
            scene.mouse.getclick()
            break

#--------------------------------------
# The clock class.

class clock:
    def __init__(self,
                 t = 0.0,
                 dt = 0.01,
                 t_max = 100.0,
                 ):

        self.t = t
        self.dt = dt
        self.t_max = t_max
        self.label = label(pos=(0,0,0),
                           xoffset=0,
                           yoffset=0,
                           text="Clock")

    def tick(self):
        self.t += self.dt

    def full_time(self):
        return self.t >= self.t_max

    def set_time(self,t):
        self.t = t

    def reset(self):
        self.t = 0

master_clock = clock(t_max=150.0)

#--------------------------------------
# Create the objects: the Master Clock
# and the other clocks

clock_separation = 50.0

x1_clock = label(pos=(clock_separation,0,0),
                 text="d = %3.2f" %clock_separation)

x2_clock = label(pos=(2 * clock_separation,0,0),
                 text="d = %3.2f" %(2*clock_separation))

xm1_clock = label(pos=(-1 * clock_separation,0,0),
                  text="d = %3.2f" %clock_separation)

xm2_clock = label(pos=(-2 * clock_separation,0,0),
                  text="d = %3.2f" %(2*clock_separation))

y1_clock = label(pos=(0,clock_separation,0),
                 text="d = %3.2f" %clock_separation)
                     
y2_clock = label(pos=(0,2 * clock_separation,0),
                 text="d = %3.2f" %(2*clock_separation))

ym1_clock = label(pos=(0,-1* clock_separation,0),
                  text="d = %3.2f" %clock_separation)

ym2_clock = label(pos=(0,-2 * clock_separation,0),
                  text="d = %3.2f" %(2*clock_separation))

def create_blink(pos):
    return ring(pos=pos,
                 thickness = 0.5,
                 axis = (0,0,1),
                 radius = 0,
                 color = color.white,
                 visible = 1)

#--------------------------------------
# label_toggle
#
# This is a function that toggles the
# labels on and off.

label_list = [scene.label,master_clock.label,
              x1_clock,x2_clock,
              xm1_clock,xm2_clock,y1_clock,y2_clock,
              ym1_clock,ym2_clock]

def label_toggle(z):
    for x in z:
        x.visible = abs(1 - x.visible)


#--------------------------------------
# Animate the scene

ready = 0
label_toggle(label_list)
while(not ready):
    ready = scene.mouse.getclick()
    label_toggle(label_list)

blink_flag=0

set_time = 10.0 # master clock reading when the signal is sent out

t1 = set_method * clock_separation + set_time
t2 = set_method * 2 * clock_separation + set_time

while(not master_clock.full_time()):
    rate(1000) # animation rate
    check_for_pause(scene)
    master_clock.tick()
    
    if(master_clock.t > set_time and not blink_flag):
        blink = create_blink(master_clock.label.pos)
        blink_flag = 1

    if(blink_flag):
        blink.radius += 1.0 * master_clock.dt

    if(blink_flag and blink.radius >= 2*clock_separation):
        x2_clock.text = "%3.2f" %t2
        y2_clock.text = "%3.2f" %t2
        xm2_clock.text = "%3.2f" %t2
        ym2_clock.text = "%3.2f" %t2
        t2 += master_clock.dt

    if(blink_flag and blink.radius >= clock_separation):
        t1 += master_clock.dt
        x1_clock.text = "%3.2f" %t1
        y1_clock.text = "%3.2f" %t1
        xm1_clock.text = "%3.2f" %t1
        ym1_clock.text = "%3.2f" %t1


    master_clock.label.text = "%3.2f" %master_clock.t




scene.label.text = ("Finished.  Close the window and\n"
                    "reopen the file to view the\n"
                    "animation again.\n"
                    "" #spacer
                    "Copyright, 2006.  Rodney Dunning.")
label_toggle(label_list)