Assignment 4: Swingers
CS 551/651 Advanced Graphics: Computer Animation
Spring 2002, Professor Brogan
Due 9:00 a.m. May 3rd
UPDATES:
April 24 - Andy continued working on the FLTK implementation and dramatically improved the performance by letting the core simulation function, draw(), execute more times before terminating. We believe this reduces the callback overhead FLTK must handle and thus speeds things up. Read his README and pay particular attention to the SPEED_UP variable which may benefit from being tuned to match your computer. Note that with this improvement, Andy's simulation returned to the same performance he observed w/o FLTK. Here's the code.
April 23 - Thanks to Andy Snyder who released a version of the code with the basic FLTK control loop added. Read his README.
Introduction
In this assignment, you will write a control algorithm for a physically simulated girl who must ride a swing. You'll have to provide a way to navigate in the OpenGL world and to monitor/update system variables using FLTK. I have provided a skeleton program (VisStud-ZIP, LINUX-TARBALL) for you to use. Compile the code, and execute the program to see what the basic controller accomplishes.
You must improve the quality of the controller so the girl leans back in the seat and kicks her legs in order to gain altitude on the swing. Also, there is a variable that releases her from the swing (you can press 'x' while the program is running to manually force her to jump). The controller you write must be able to activate the release variable so the girl lands a prespecified distance from the swing. As a user of your system, I will use the user interface to set the value of the variable ls.landingSite and you must control her swinging actions and the release variable to have her hit the ground at that specified location (plus or minus 0.25 meters). The ls.landingaSite variable may be positive or negative and may be bigger than your swinger can accomplish (select a release point that does the best you can).
Details
The skeleton code that I have provided uses OpenGL/glut, the machine generated code of a physical simulation toolkit (SD-Fast), and some home-grown code. After executing the swinger program, the OpenGL window fires up and you should see the girl start swinging. There are many files included in this code distribution. You can ignore most of them. In fact, you can do all of your control system programming solely in the swing.cpp file. You'll end up making changes to main.cpp also because you're adding FLTK and mouse interface controls. Here are some hints to understand the code. Nearly all variables are global. Please send me your questions before wasting a lot of time learning it. The variables have cryptic names and I'll cc the class on any explanations
| Variable Name | Meaning |
| st | State vector array |
| tau | Array of torques applied to the degrees of freedom |
| st_d | Array of desired values for state vector components |
| ls | A freely organized array of useful variables |
In the swing.cpp code, you'll see that the function swing() does the work of the control system state machine. The function determines desired positions for the shoulder, elbow, hip, and knee joints. The function also updates the current control system state of the character (moving backward/downward or forwards and up, etc.). You may (and probably should) improve the system by adding new states, changing when transitions occur, and by changing what is done in each state. For example, the following variables can be tweaked in the current implementation to achieve different results: ls.shld_folded, ls.shld_unfolded, ls.elb_folded, ls.elb_unfolded, ls.hip_bend, ls.legs_out, ls.knee_bend, ls.knee_out. But you should ask yourself when you really transition from a tuck to a layout position when swinging. Is it really at the peaks of the motion?
Also note the variable ls.dynState will release the girl from the swing as soon as it is set to 1.0 (see the keyboard handler event for 'x' in main.cpp). You'll want to add code to your swing functions that automatically sets this variable to 1.0 at the appropriate time to accomplish the correct jumping distance. When the girl hits the ground, the simulation stops and her jumping distance (when her center of mass reaches the ground plane) so I can inspect the value of her st.x value, her distance from the swingset.
If you want to see the initial values of any of the variables of the character, look in legui.cpp. Remember that the character's state is defined by the x/y/z of the center of mass, the orientation (quat{1234}) of the center of mass, and the joint rotations of each degree of freedom. The joints are arranged in a hierarchy, so the shoulder angle moves both the upper and lower arms. Hopefully the st variables have somewhat intuitive names. If not, ask me.
You will be graded both on how well she hits the desired spot and how long it takes her to get there. I don't care about how long it takes your simulation to execute, but I want to minimize the time in 'simulation seconds.' You can view the variable dynstime.time to see how time passes.
Viewer Interface
Currently, the camera is fixed with a particular LookAt value. You should add a mouse interaction that allows the user to change perspective and zoom in. You'll also have to add the FLTK interface.
Simulation Interface
The simulation interface is convenient for debugging and it is convenient as a user interface. Here are some things I require and suggest FLTK include in the interface:
|
Buttons - Required |
|
|
Start |
set ls.run to -1.0 (run indefinitely; set to a positive number to run for n-seconds) |
|
Stop |
set ls.run to 0.0 (stop running) |
|
Output Only - Required |
|
|
Time |
dynstime.time |
|
Input Only - Required |
|
|
Landing Site |
ls.landingSite |
|
Output Only - Suggested |
|
|
Current State |
ls.inx |
|
Current velocity (in world coords) |
ls.cmxd, ls.cmyd, ls.cmzd (stands for center of mass {xyz} velocity) |
|
Current velocity of angle of upper swing rope |
st.swingl_yd |
|
Current angle of upper swing rope |
st.swingl_y |
|
Input/Output - Suggested |
|
|
How straight are upper legs? |
ls.legs_out |
|
How straight are lower legs? |
ls.knee_out |
|
How bent is upper leg? |
ls.hip_bend |
|
How bent is knee? |
ls.knee_bend |
|
How folded is upper arm? |
ls.shld_folded |
|
How folded is lower arm? |
ls.elb_folded |
|
How straight is upper arm? |
ls.shld_unfolded |
|
How straight is lower arm? |
ls.elb_unfolded |
Turn in
____ If using Microsoft Studio, build your project so FLTK and OpenGL includes and libraries will be in the default locations. You shouldn’t have to update your project properties to compile and link.
____ First thing in the README must be instructions for how to run your
application (are there command line arguments?).
____ Zip your source code and README (not the executable or object
files).
____ The zipped directory name must include your name or userID (I’m
tired of unpacking “assignment 4” turnins and then moving them to another
directory to avoid overwriting).
____ Attach turnin file to email with your name or email in the file
name.
____ Submit turnin zip file to dbrogan@cs.virginia.edu.
Q & A
I
recently made a change to swing.c and I think the explanation of the change may
be useful to you all. The old switch condition to
BACKWARD_AND_DOWN was:
if (ls.cm_zd < 0)
I changed it to:
if ((ls.cm_zd < 0) && (st.swingl_yd < 0))
Here's why this works better. ls.cm_zd is the variable that indicates
the velocity in the z direction (zd) of the girl's center of mass (cm),
which is at her belly. Problems were caused when she was in the
BACKWARD_AND_UP state and her body twisted, causing her ls.cm_zd to
momentarily become negative. The system would then prematurely
transition to BACKWARD_AND_DOWN. This fix requires that her COM z
velocity be negative AND the rotational velocity of the chains of the
swing be moving forward before switching states.
dynstime.time just keeps track of the simulation's version of time. The value at startup isn't important, but the progression of time while running the simulation is important.
Should I worry about the Ramp function at all or just more about adding states
and position variables?
The 'slope' values of the ramp functions are parameters you can
play with. Unfortunately, playing with these variables requires
a recompile the way the system is set up now.
I recommend playing with the number of states, the functions that
define the transitions between states, and the 'ls' variables that
define joint positions for the states.
I've tweaked around with all of the limbs, including neck and ankles. But,
I can't get the shoulder to move as I want it to. Is there a constraint set on
those limbs within the code? For example, if I wanted her arms to be straight
out in front of her, her shoulder would be -pi/2 and her elbow should be 0. But
it's not giving me that result.
Note that the ls.shld_unfolded and ls.elb_unfolded need be changed
in unison. The girl can't straighten her elbows all the way without
also changing the angle of her shoulder. To figure out how the
two angles change, draw a triangle. The length of one side is
0.339 (length from hands to the swing seat), another is 0.223
(the length of the upper arm), and the last is 0.167 (the length
of the lower arm). Play with the trig to change the angles of
the triangle while preserving the lengths of the sides.
What are the values of individual positions relative to? for example: st.hipr_y,
st.kneer_y, etc.
All the rotational parameters are measured in radians. The 0-angle
for these joints occurs where the girl is standing straight up,
with her hands at her side and her feet flat on the ground. So, a
knee or hip value of 0, should result in the joints making a 0 radian
angle between the inboard and outboard bodies.