Virtual Juggling

From Wayfarer
Balljuggling.png

Final Project
Physically Based Modeling
Comp 290.072
Spring 2000

For my final project in Physically Based Modeling (Comp 290.072) I have chosen to implement Virtual Juggling. This project uses physically based models for the objects being juggled and robotic style "mirror laws" to enable the hands to catch the juggled objects.

The Problem of Juggling

Juggling presents a nontrivial, dynamic environment in which to simulate. There are normally multiple projectiles with interweaving paths. Human jugglers must use their hand-eye coordination to decide where the ball or club will be so that the hand may be placed in a position to catch it. Although a computer, if the programmer wanted to, could use its inherent knowledge of the complete state of its world to automatically calculate the best position to catch an object, I have chosen not to do this. Rather, just like a human juggler, my application makes use of only the current state of the world to decide where to place the hands when catching. It does this using robotic style "mirror laws" (which are explained below). This approach, I believe, more closely approximates how real jugglers juggle.

Real Juggling

Real juggling can be done with almost any type of prop. Most props, however, fall into three different categories typified by the 3 most common juggling props: balls, rings, and clubs. These three props have very different characteristics that affect how they are juggled.

Balls

With balls, all axes are equal and if the prop rotates in flight it does not matter.

Rings

With rings, two axes are equal and one is small enough to be effectively nonexistent. This affects how the prop can rotate. Any rotation around the small axis is inconsequential, but rotation around either of the other axes can be difficult to control.

Clubs

With clubs, two axes are relatively equal while one is fairly large (compared to the other two). This forces the club to rotate around an axis perpendicular to the juggler during the act of juggling.

No matter what type of prop used, there are several basic patterns employed in juggling. For a single juggler, the basic patterns are the cascade, fountain, shower, and multiplexing. A cascade is the standard juggling pattern where balls are alternatively thrown from one hand to another. It is normally used when juggling an odd number of objects. In the fountain pattern, balls are thrown and caught by the same hand. It is traditionally used for patterns consisting of an even number of objects. The shower pattern is the most commonly depicted juggling pattern. In a shower, all the balls are thrown in a circle. Even though many non-jugglers think of this pattern when thinking of juggling, it is a much more difficult pattern than either the cascade or the fountain. Multiplexing is when a juggler throws more than one object from a single hand simultaneously.

Patterns between multiple jugglers are based on the single person patterns. Most commonly, two jugglers will juggle in synchronized cascade patterns and periodically throw objects to the other person instead of to themselves. This is called passing. Another form of juggling involving multiple juggling is "buddy juggling." In buddy juggling, two people juggle as though they were only one person. One person can do all the juggling for one side while the other juggles for the other side (i.e. one person juggles the right hand and the other the left hand) or the jugglers can alternate which side they juggle. This can lead to many interesting effects where the objects being juggled go in a standard pattern while the jugglers interweave between each other.

The Physics of Juggling

Juggling makes use of several key concepts. First, all motion, even that with complex rotation, can be considered standard projectile motion. Second, juggling patterns make use of periodic cycles. Patterns repeat, rather than change continuously. Third, the number of fundamental patterns is small. Through the use of these concepts juggling can easily be understood. Before we dive into that, however, let us define a few variables and equations.

Some Definitions

Lets call the time between consecutive throws for one hand tau. Each hand travels in a circular pattern that has two states: holding an object and not holding an object. Let's call the time in which a hand is holding something the dwell time. The dwell time is obviously smaller than tau since tau is composed of both the dwell time and the non-dwell time. We not really concerned about the absolute length of the dwell time, but rather how does the dwell time compare to tau. Therefore, let's call theta the fraction of tau that is the dwell time. An immediate observation we should make is that theta will always be between 0 and 1 (and never equal to either). Given that, the dwell time (or the time an object spends in the hand) is tau * theta. Let's call the number of objects being juggled n.

Now, with those variables, let's give a few useful equations. First, let's consider the case where n is even. If n is even, then each hand (we're assuming two hands here) holds 0.5 * n objects and one full "cycle" of juggling (that is, at the end of the cycle, the objects are in the same location as when the cycle started) lasts for 0.5 * n * tau. However, because of the dwell time, the first object must land theta * tau earlier (that is, we consider the cycle to end when the last object is caught, not after its dwell time). Therefore, the time each object spends in the air (let's call it t) is equal to 0.5 * n * tau - theta * tau or simplified: t = 0.5 * tau (n - 2 * theta).

Since we know how long an object spends in the air, we can use the standard equation of projectile motion to determine how high the ball goes. The standard equation of projectile motion is r = r0 + v0*t + 0.5*g*t^2. (This can be found in any physics text.) At the apogee (that is, the highest point of the parabola made by the path of the object), the velocity of an object will be 0. If we also assume that the object was launched from a height of 0, we get the equation h = 0.5 * g * t^2 (note that ^ is the exponentiation operator). However, the t we calculated previously is actually twice the value of the t in this equation. Therefore, to unify the two equations, we must rewrite it to be: h = 0.5 * g * (0.5 * t)^2 or simplified: h = (1/8) * g * t^2. Substituting the value of t calculated previously, we get h = (1/32)*g*[(n-2*theta)^2]*tau^2.

We need to know, however, what initial velocity will allow us to reach the height h. At h, the velocity v will be equal to v0 - g*t1. Solving for t1 (the time to get to h), we get t1 = v0/g. We can substitute this into the standard equation for projectile motion and solve for v0. The equation starts out as h = v0 * (v0/g) - 0.5 * g * (v0/g)^2. Simplifying, we get v0 = sqrt(2*g*h). This gives us the initial velocity needed to reach a height h.

Some observations to be made are that tau and h are the limiting factors for successfully maintaining a juggle. Higher values of h must be aimed more accurately and smaller values of tau determine how fast a juggler must aim. While h is dependent upon the number of objects juggled (thereby ensuring that as the number of objects increase, the difficulty increases), tau can usually be adjusted. Most often tau falls in the range of 0.2 seconds to 0.8 seconds with a many jugglers having a tau of 0.5 seconds. Another factor in creating a stable juggling pattern is the value of theta. The vast majority of jugglers have a theta very close to 0.5 (i.e. the object is held for half the time the hand takes to travel in a circle). This encourages a strong pattern by ensuring that as one hand is throwing, the other is catching.

What About Club Juggling?

Club juggling introduces two extra considerations into a juggling pattern: 1. the club rotates, 2. clubs are generally caught in only one place -- the handle. How can we adjust our equations to take club spin into account?

Club rotation is a byproduct of the lever arm going from the elbow to the hand. With that in mind, let's call L1 the length from the elbow to the handle of a club. Let's also call L the length from the elbow to the club's center of mass (which is normally in the round area at the top of the handle). We'll use omega as the angular velocity of the pivot arm. Now, the velocity at the center of mass is given by the equation v0 = omega * L. The time the center of mass spends in the air is calculated similarly to how we calculated the initial velocity to reach a height h. To reach a height h we used the equation t1 = v0/g. The time spent in the air is twice this (t1 is the time going up which equals the time going down), so the time the center of mass of the club spends in the air is t = 2*v0/g = 2*omega*L/g. The club handle, however, since it is rotating, travels at a different speed. This speed is given by the equation v1 = omega * (L - L1). If we want the speed of the handle in the frame of reference of the center of mass, we can just subtract the two velocities: v0 - v1 = omega * L - omega * (L - L1). Note that the handle rotates with the same angular velocity omega that the pivot arm rotated with, and since we catch the club by the handle, it must rotate by 2*PI*m radians for m number of rotations. This allows us to calculate how long the club must stay in the air, based on the number of rotations it makes. This value is t(m) = 2 * PI * m / omega. An interesting observation is that t(m) must be equal to the t we previously calculated (since both are how long the club stays in the air). Therefore, we get the equation: 2 * PI * m / omega = 2 * omega * L /g or rearranging the variables: omega = sqrt(m * PI * g / L).

The throw height can be calculated using the same formula we used for balls (h = (1/8)*g*t^2), so we can substitute for t and get the following equation: h(m) = (1/8)*g*t(m)^2 = (1/8)*g*(2*PI*m/omega)^2 = m*PI*L/2. The most striking thing about this equation is that it no longer contains g. This is because in a lower gravity the club must be released slower to reach the same height and in releasing slower, since angular velocity is a byproduct of the arm motion, less spin is imparted to the club. With a lower gravity, however, the club will travel further by the exact amount needed to compensate for the slower angular velocity.

So, to recap, here are the basic equations of juggling:

tau = Time between consecutive throws of one hand.
theta = Fractional dwell time (Note: 0 < theta < 1).
tau * theta = Time an object spends in a hand.
n = number of objects juggled.
t = (1/2)*tau*(n - 2*theta) = the time an object spends in the air
h = (1/32)*g*[(n - 2*theta)^2]*tau^2 = the height an object reaches when thrown.
v0 = sqrt(2*g*h) = the initial velocity needed to reach height h.

and for clubs we added the following equations:

L1 = length from elbow to handle of club.
L = length from elbow to center of mass of club.
omega = angular velocity of pivot arm.
v0 = omega * L = velocity of center of mass
t = 2*v0/g = 2*omega*L/g = time center of mass spends in the air
v1 = omega*(L - L1) = velocity of club handle
v0 - v1 = omega*L - omega*(L - L1) = speed of handle in relation to the club center of mass.
m = number of rotations a club makes while in the air.
t(m) = 2 * PI * m / omega = the time a club stays in the air (based on the number of rotations it makes)

We then noted that t = t(m) and used that to get the following equation for omega:

omega = sqrt(m * PI * g / L)

and plugged that into the equation for h to get:

h(m) = m * PI * L / 2

which is equal to h but does not depend on g at all! (And, in addition, it is a linear equation.)

Note: the majority of this information was taken from Magnusson. Some equations were taken from Sears (see references).

Modeling Juggling

So, how do we go about modeling juggling in a computer program? First of all, we need to figure out what needs to be modeled. At a minimum, the object being juggled need to be modeled. This will normally be either balls, clubs or rings. Balls can be modeled with particle system dynamics. Clubs and rings, because of their shapes, need more than what a particle system offers. A rigid body system works well in this case.

In addition to the object being juggled, the hands of the juggler must also be modeled. The juggler's hands go through several recurring states while juggling. This simplifies the task presented to the programmer. First of all, a hand is either holding one or more objects, or the hand is not holding any objects. Second, the hand is generally moving in one of three states: launching an object, resetting to launch another object, or tracking an object to be caught. In the launching state, a hand moves rapidly, moving from one direction to another (generally from the outside of the body to the inside), while holding an object. Upon reaching a "launch point" (that will generally not vary per hand) the object is "let go" and allowed to fly freely. The reset state is used when, just after launching an object, a hand still holds an object to be thrown. In this case, the hand moves rapidly outward to where the launching state starts at which time it enters the launching state again. Once all the balls have been thrown from a hand, the reset state is no longer used and instead the tracking state is used in its place. In the tracking state, a hand follows a path designed to let it intercept and catch a flying object.

The tracking state is perhaps the most interesting part of modeling juggling. Several robotic jugglers have been built that keep one, sometimes two, balls in the air by bouncing them, similar to using a paddle to bounce a ball in the air. These robots use something called a "mirror law" to make sure their "hands" are in the right place at the right time in order to "catch" and "throw" the ball. The robotic hand tracks the flying ball presents a "distorted mirror" of it. That is, given a plane where the "hand" and the ball come together, as the ball moves away the "hand" moves away a proportional amount in the opposite direction. This image illustrates this concept:

Mirror-law.png

The term "mirror law" is actually since there is not just one "law" that is used. Rather, it is a collection of various laws that are used depending on the situation. Our goal is to develop mirror laws for ball and club juggling.

Mirror Law for Ball Juggling

Let's assume the following arbitrarily chosen coordinate system: X-up, Y-left, Z-back. One good thing about juggling is that it tends to stay within a plane, so for all practical purposes we do not have to worry about the Z coordinate. Therefore, the first portion of our mirror law is the following equation:

hand(z) = ball(z)

The mirror law tells the hand where to move from the launching position to the catching position. The launching position should not change (launching from the same spot every time encourages a stable juggling pattern), but the catching position may, depending on the initial velocity of the thrown ball. One thing every juggler learns is that the best way to catch a ball is not to reach up to grab it, but rather to let it come down to your hand. This also encourages a stable pattern, so we should encode this into our mirror law.

hand(x) = launch(x)

This says that the height at which the ball is launched will be the height at which a ball is caught. In real juggling, inertia won't let us do this completely but in virtual juggling it is a close enough approximation.

Finally, we need to figure out how to make the hand move from left to right (or vice-versa) from launching to catching position. We assume that the hand will not be tracking a ball until it has launched a previous ball. Because of this, the position of the incoming ball may vary in its location at the time of the outgoing ball's launch. Since the position of the catch will ultimately be outside (from the body's perspective) of where the ball was launched, we do not want the hand to come inside just to go outside when the ball passes over the launch position. Therefore, we need an equation that will keep the hand moving from inside to outside proportionally to where the ball to be caught is. If the ball is directly over the hand, this is easy, just follow the ball with the hand. If the ball is has not gone over the hand yet, the hand should still move outside (towards a "goal" catch location which represents the ideal location to catch the ball), but slower than the ball to allow the ball time to catch up. If the ball has already passed the hand, we want to quickly move the hand to be under the ball and start tracking from there. One thing to immediately note is that the equation will be different depending on which side of the body is in question. The left hand deals with increasing Y while the right hand deals with decreasing Y. Therefore, here is the mirror law I have designed: (Note that ball0(y) is the y location of the ball at "acquisition" or where the hand starts tracking the ball right after launching the previous ball. The catch(y) constant is a idealized location of where the juggler would like to catch the ball. The ball may be caught there, or it may not, but this gives us a location to aim for.)

Left Hand:

If (ball(y) > hand(y)) then

hand(y) = ball(y)

else

hand(y) = launch(y) + [(ball(y) - ball0(y)) / (catch(y) - ball0(y))] * (catch(y) - launch(y))

Right Hand:

If (ball(y) < hand(y)) then

hand(y) = ball(y)

else

hand(y) = launch(y) + [(ball(y) - ball0(y)) / (catch(y) - ball0(y))] * (catch(y) - launch(y))

Note that the only difference between the two laws is the comparison at the beginning. This is because the signs of the terms involved will automatically interpolate the hand in the correct direction. So, what exactly does this equation do? From the point at which the previous ball is launched, move the hand towards an ideal "catching point" proportionally with how the ball is moving towards that point from where we started tracking it. This works well, as long as the ball will be coming down in the area near the ideal catch point. If it comes down too soon or too late (that is, too far in or out), the hand will likely not be in the correct position. This models the fact that some balls can be uncatchable. A better method, perhaps, might be to proportionally move out in relation to how far the ball has come down.

Mirror Law for Club Juggling

Club juggling is very similar to ball juggling so we can reuse several of our equations from the ball juggling mirror law for our club juggling mirror law. The difference between club and ball juggling is that while a ball can be caught at any point in flight, a club is normally only caught by the handle and only when the handle is close to a certain position. If we designate that a club is at 0 degrees rotation at the launching point, then the club will also be at 0 degrees when caught. The club may rotate several times but will always end up at 0 degrees when being caught. Therefore, we need an equation for hand(x) that takes this rotation into account while smoothly going from where the hand launches the club to where the hand catches the club (the actual catch location, not an idealized catch location). Assume we can track the current rotation of the club and that at any given instant we know how far the club has rotated from when it was thrown. (i.e. a club will rotate 2*PI*m radians until caught where m is the number of spins it makes while in the air). Therefore, an equation that will equal 0 at club acquisition (where we first start tracking it) and 1 at catch (assuming we catch it at m rotations) is the following (let's call the angle of rotation theta and the rotation at acquisition theta0):

(theta - theta0)/(2*PI*m - theta0)

At acquisition, theta = theta0 so the equation equals 0. Upon catching, theta = 2*PI*m so the equation equals 1. Since we want to go from where we launch the previous club to where we catch the club, let's use this equation to smoothly blend between the two locations:

hand(x) = launch(x) + [(theta - theta0)/(2*PI*m - theta0)]*(club(x) - launch(x))

Since our previous equation varies from 0 to 1 between acquisition and catching at acquisition hand(x) will equal launch(x). At catching, when theta = 2*PI*m, the equation becomes hand(x) = launch(x)+club(x)-launch(x) = club(x).

The equations for hand(y) and hand(z) can be directly used from the ball mirror law since the rotation only changes the height at which the club is caught.

In addition, it is often useful to use collision detection with the flying objects. This presents a more realistic experience, especially since real jugglers tend to have objects collide at times. In the best case, however, collision detection should not be needed because in correct juggling the objects should not collide with each other.

My Juggling Application

Specifications

In my project proposal I had specified that I wanted to simulate club juggling. The basis of my proposal was to do this using something similar to robotic mirror laws. Due to various reasons, I decided to model ball juggling as a precursor to modeling club juggling. This also follows the normal progression of most real jugglers who learn to juggle balls before learning to juggle clubs. Also, as we saw above, the mirror laws for ball and club juggling are remarkably similar. Unfortunately, time ran out before I could continue on to modeling club juggling, so my program as presented only juggles balls. All of the work done on this, though, is directly applicable to club juggling.

I had planned to use collision detection in my program, but when I got into the program I deemed it unnecessary in proving that the mirror laws work. While it is most definitely on the "to do" list, it has dropped in priority.

For club motion, I had planned on using rigid body dynamics. That is still the goal, but for balls, a rigid body system is overkill. Instead a particle system is used to simulate ball motion.

For the movement of the hands, I specified that mirror laws would be used to allow the hands to track the objects being thrown.

Implementation

As I said above, my implementation is one of ball juggling. Currently it only juggles 3 balls, but it would be trivial to adapt it to higher numbers of balls. For the motion of the balls, I use particle dynamics with an Euler integrator. A better, but more complicated choice might be to use a Runga-Kutta integrator. The particle system and integrator are encapsulated into the Ball class so the other classes do not have to worry about them.

For the movement of the hand from catch position to launch position, I use a Hermite spline. A Hermite spline takes two points and two vectors. The two points are obviously the catch point (wherever it ends up being) and the launch point. The two vectors are as follows. For the catch point, I use a vector that points straight down. This causes the hand to move straight down after catching a ball, mimicking a juggler that "cushions" a caught ball. For the launch point, I use a vector that points in the direction the ball will be launched. In the case of three balls, this is exactly at a 45 degree angle. For higher numbers of balls, it would need to be a higher value. This vector assures that the hand travels in the direction the ball will be throw at just before the act of throwing. One other thing to note is that I have made the vectors be the same length. This assures a uniform hand speed from catch point to launch point. One possible future enhancement would be to calculate the size of the vectors needed to make the hand move at the appropriate speed at launch time. The amount of time between catch and throw is determined by the fractional dwell time multiplied by the time between consecutive throws in one hand (theta * tau).

For the movement of the hands in the reset state, I use a simple circle interpolation. This could easily be replaced by another Hermite spline interpolation, but it would probably be overkill. Once again, the time spent in the reset state is calculated similarly to the time in the launch state, but this time theta*tau is subtracted from tau (tau - theta*tau).

For the movement of the hands while tracking, I use the output of the above mirror laws directly. There is one artifact of the above mirror laws that could possibly use refinement. Immediately after the launch point, there is sometimes a small jump of the hand to the outside of the body. Currently, I do not believe it is jarring enough to warrant fixing.

Results

The results of my program can be seen in this video <videoflash>tqH3quj07cU</videoflash> For a look at how the program ran when I first got it to juggle, you can look at <videoflash>RqDRIN-wuOQ</videoflash> Note that I had not yet added spline interpolation from catch point to launch point. Instead I was using simple circle interpolation like I use for the reset motion. As a result, there is a discontinuity between catch point and the start of launching motion. Also note that I was attempting to make the hand move in a circle while tracking. This resulted in the balls being caught at higher locations than desirable. Because of this, I decided to make the hand(x) mirror law be just the same as the launch(x) location. Also note that time is slowed down to about 1/4th of normal time in these videos (that is 4 seconds of video time = 1 second of what would be real time). This was done to allow the viewer to actually see the acts of catching, throwing, launching, tracking, etc...

The source to my application can be found here. Note that this is a GLVU application that expects to be placed as a subdirectory in the main glvu tree. Note also that GNU make is required for compilation. I have successfully compiled and run this application under Linux. There is nothing, however, than should preclude compiling and running it under Windows or Irix.

Future Work

My application is only a starting point from which to proceed with juggling simulations. As it currently stands, the application only works with three juggling balls. Adapting it to n number of balls would be trivial. Also, there is a standard method of indicating juggling patterns called "site-swap" that could be integrated into the program. Site-swap allows a juggling pattern to be specified by a sequence of numbers. This would allow the program to model a much wider range of juggling patterns.

Another interesting modification would be to have the virtual juggler juggle clubs instead of balls. I have outlined above a version of the mirror law that should work for clubs. Club juggling, however, involves more than just a modified mirror law. While balls can be modeled using particle dynamics, clubs must be modeled with something more, ideally using rigid body dynamics. The hand motions must be modified to swing the clubs, not only in the correct direction for rotation, but also for moving the head of the club in the right direction for the throw (when caught, the head of a club points in the opposite direction of where it will next be thrown). Quaternion interpolation would be a good candidate to add to the current spline interpolation between catch point and launch point.

In addition, other things could be added to fill in some aesthetic issues. One of the most jarring aspects of my current application is the lack of a human body. At a minimum an articulated human model could be added and the hands placed in the proper locations using inverse kinematics. A better choice would be to add in a dynamically skinned model that would look much more real. Movement of the fingers when catching an object would also add to the realism.

Further advanced work would be to place the entire system within a virtual environment and allow the virtual juggler to pass back and forth with a human juggler. At a minimum, some method of tracking the humans hands in 3-D space would be needed. It is doubtful that current magnetic trackers would be up to the task as the movements involved happen quickly. A hi-ball setup would be limited by the fact that in current setups it can only track if pointing mostly upward. In order to track the hands well enough, accelerometers would probably be needed. Assuming, however, that a user's hands can be tracked, and the user can be taught some method of indicating when an object is to be thrown (i.e pressing a button on a python joystick), a mirror law for an incoming object would need to be developed to allow the virtual juggler to accurately track and catch the thrown object. This mirror law will most likely closely follow the above mirror laws.

Another thing that could be done would be to actually record motion capture data from a real juggler and integrate this into the simulation. You would need to blend between the simulated values for hand movement and the motion captured values for hand movement but it is possible that even more highly realistic motion could occur as a result of this.

Conclusion

My application successfully simulates 3-ball juggling. It uses robotic mirror laws to enable the hands to track incoming balls, particle system based motion for the balls, and spline interpolation for moving the hands while launching the balls. Although I did not end up simulating club juggling, I was able to prove that mirror laws for normal juggling (as opposed to the robotic ball bouncing) work and that they can form stable juggling patterns. My application forms a solid base on which a club juggling simulation, or any other type of juggling simulation, can be built.

References

  • Aboaf, Eric W., Steven M. Drucker, and Christopher G. Atkeson, "Task-Level Robot Learning: Juggling a Tennis Ball More Accurately", Proceedings 1989 International Conference on Robotics and Automation, pp 1290-1295.
  • Andersson, Russel L., "Understanding and Applying a Robot Ping-Pong Player’s Expert Controller", Proceedings 1989 * International Conference on Robotics and Automation, pp 1284-1289.
  • Baraff, David and Andrew Witkin. Course Notes, Physically-Based Modeling. SIGGRAPH 1998.
  • Beek, Peter J & Arthur Lewbel, "The Science of Juggling", Scientific American, November, 1995, Volume 273, Number 5, pp 92-97.
  • Bühler, M, D.E. Koditchek, & P.J. Kindlmann, "A Family of Robot Control Strategies for Intermittent Dynamical Environments", Proceedings 1989 International Conference on Robotics and Automation, pp 1296-1301.
  • Bühler, M & D.E. Koditchek, "From Stable to Chaotic Juggling: Theory Simulation, and Experiments", Proceedings 1990 International Conference on Robotics and Automation, pp 1976-1981.
  • Mason, Matt, "A Survey of Robotic Juggling and Dynamic Manipulation" (http://www.juggling.org/help/misc/robots.html).
  • Magnusson, Bengt and Bruce Tiemann, "The Physics of Juggling", The Physics Teacher, 27 (1989) pp 584-589.
  • Rizzi, A.A. & D.E. Koditscheck, "Progress in Spatial Robot Juggling", Proceedings 1992 International Conference on Robotics and Automation, pp 775-780.
  • Sears, Francis W., Mark W. Zemansky, and Hugh D. Young. University Physics 7ed., Addison-Wesley, 1988.
  • Shannon, Claude E., "Claude Shannon’s No-Drop Juggling Diorama", Claude Elwood Shannon Collected Papers, Ed. Sloane & Wyner. 1993.
  • Shannon, Claude E., "Scientific Aspects of Juggling", Claude Elwood Shannon Collected Papers, Ed. Sloane & Wyner. 1993.