Pages, some stolen, some original
▼
Saturday, August 16, 2008
OpenGL Gear Train Program
OpenGL is a computer programming library for displaying 3D images (GL=Graphics Library, Open is for open source).
I haven't been posting much lately partly because I have been busy messing with an OpenGL program. I have some ideas for some do-dads involving gears, and I was looking for a way to make some digital drawings. Gears are kind of problematic. They have been around forever, and they have evolved into some of the most esoteric mechanical engineering devices around. So there are great and glorious CAD/CAM packages out there that will draw and design gears, but they cost a ga-zillion dollars and take six years to master. I just wanted to be able to sketch out some elementary gear like shapes and be able to generate a digital animation.
So I poked around for a bit and I finally stumbled across a set of programs written by Shobhan Dutta using OpenGL. The best part was he provided source code that compiled on my machine! One of his programs animates a configurable gear train. It is not very elaborate, but it compiles, it runs and it displays gears! This is great! I think this may have been written when he was a graduate student some ten years ago or so.
Of course, it needs a little work. First of all there is no provision for controlling the speed of the gear train. The gears are either spinning or stopped. Modifying the program to provide for speed control takes some doing. Most of the program is pretty clear and straight forward, but the section that sets the relative speeds of the gears is long, involved and basically opaque.
I spent part of a day or two trying to sort it out, but eventually decided to simply replace it with my own version. I like to think my version is simpler and easier to understand, but the amount of source code is similar to the original. But it works and I can now control the speed.
Of course one thing leads to another and now I have small laundry list of problems to fix. The first one was ensuring that the gear teeth properly mesh. This is not a physics engine, it is only drawing 2-D planes in a 3-D space. Gears grind right through other gears unless you (the programmer) takes pains to see that they don't. I got spur gears to mesh, but bevel gears are not cooperating. I think I need a new model to determine proper phase alignment of bevel gears. It's going to take some work.
Then there are the belts. Right now the program uses plain flat belts of no discernible thickness, and as they are all black, they do not appear to move. I am toying with the idea of making them toothed belts, so they engage the gears, or making them V-belts, but with writing on the back, so you can see that they are moving.
There is also a small bug in the belt drawing routine that leaves a little space on the bottom side of the belt. I am going to have to sort out the math in order to figure out what is going on with this one.
I didn't like the way bevel gears were being drawn. I changed that so they look better, but they could still use some improvement. I have sorted out the math for this, I just need to write it down, but the phase problem is still bugging me.
I have also done a lot of house cleaning. Gotten rid of duplicate computations, made common blocks of code into subroutines (like drawing a circle). Added a primitive help function and some more error checking.
The big thing will be when I add ring gears and rotating frames. I hope that doesn't make it too complicated.
Update October 2016 replaced missing image.
I just glanced through your page. I'm Shobhan Dutta and wrote the original programs. Glad that you found them useful.
ReplyDeleteShobs
Dear Mr. Dutta:
ReplyDeleteI tried to get in touch with you when I was first started on this, but no luck. I am very pleased that you found my post.
This project has taken on a life of it's own, which is very good. I need something to do, begin unemployed and all.
I modified the program to use GLUT in hopes that I could port it to Linux. Changing to GLUT was a piece of cake compared to converting to Linux.
Having a working program to start with has made this project possible. Without it I would still be floundering. Thank you.
#--------------------------------------------------------------------#
ReplyDelete# This makefile is templated from by 'cbp2make' tool rev.80 #
# #
# rev who remark #
# --- ------ -------------------------------------------------- #
# 0 sunlg1 base generic template #
# #
# build the directories to hold src/bin #
# wget the source from https://github.com/Bogwon/Gears into ~src #
# dos2unix the src.c to get rid of CTRL-M's c #
# comments : put the testc.gear in ~/bin #
# comments : put the .c / .h in ~/src #
# comments : make clean #
# comments : make #
# #
# comments : ../bin/GLBogwonGears #
#--------------------------------------------------------------------#
#
WRKDIR = `pwd`
# ---------------------------------------------------------------------------
CC = gcc
CXX = g++
# ---------------------------------------------------------------------------
INC =
#CFLAGS = -std=c++11 -Wall
CFLAGS = -Wall
RESINC =
RCFLAGS =
LIBDIR =
#LIB = -lglut -lGLU -lGL -lm
#LIB = -lGL -lX11 -lXext -lm
LIB = -lglut -lGLU -lGL -lm
LDFLAGS =
# ---------------------------------------------------------------------------
INC_RELEASE = $(INC)
CFLAGS_RELEASE = $(CFLAGS) -O2
RESINC_RELEASE = $(RESINC)
RCFLAGS_RELEASE = $(RCFLAGS)
LIBDIR_RELEASE = $(LIBDIR)
LIB_RELEASE = $(LIB)
LDFLAGS_RELEASE = $(LDFLAGS)
OBJDIR_RELEASE = objs
DEP_RELEASE =
OUT_RELEASE = ../bin/GLBogwonGears
# ---------------------------------------------------------------------------
OBJ_RELEASE = $(OBJDIR_RELEASE)/draw_gears.o $(OBJDIR_RELEASE)/gl_drawing.o $(OBJDIR_RELEASE)/load_data.o $(OBJDIR_RELEASE)/normal.o $(OBJDIR_RELEASE)/prep_data.o $(OBJDIR_RELEASE)/main.o
all: release
clean: clean_release
before_release:
test -d ../bin || mkdir -p ../bin
test -d ../bin || rm ../bin/*.o
test -d $(OBJDIR_RELEASE) || mkdir -p $(OBJDIR_RELEASE)
after_release:
release: before_release out_release after_release
out_release: before_release $(OBJ_RELEASE) $(DEP_RELEASE)
$(CC) $(LIBDIR_RELEASE) -o $(OUT_RELEASE) $(OBJ_RELEASE) $(LDFLAGS_RELEASE) $(LIB_RELEASE)
# ---------------------------------------------------------------------------
$(OBJDIR_RELEASE)/draw_gears.o : draw_gears.c structure.h normal.h
$(CC) $(CFLAGS_RELEASE) $(INC_RELEASE) -c draw_gears.c -o $(OBJDIR_RELEASE)/draw_gears.o
$(OBJDIR_RELEASE)/gl_drawing.o : gl_drawing.c structure.h draw_gears.h load_data.h
$(CC) $(CFLAGS_RELEASE) $(INC_RELEASE) -c gl_drawing.c -o $(OBJDIR_RELEASE)/gl_drawing.o
$(OBJDIR_RELEASE)/load_data.o : load_data.c structure.h
$(CC) $(CFLAGS_RELEASE) $(INC_RELEASE) -c load_data.c -o $(OBJDIR_RELEASE)/load_data.o
$(OBJDIR_RELEASE)/normal.o : normal.c structure.h
$(CC) $(CFLAGS_RELEASE) $(INC_RELEASE) -c normal.c -o $(OBJDIR_RELEASE)/normal.o
$(OBJDIR_RELEASE)/prep_data.o : prep_data.c structure.h prep_data.h
$(CC) $(CFLAGS_RELEASE) $(INC_RELEASE) -c prep_data.c -o $(OBJDIR_RELEASE)/prep_data.o
$(OBJDIR_RELEASE)/main.o : main.c structure.h draw_gears.h gl_drawing.h load_data.h prep_data.h
$(CC) $(CFLAGS_RELEASE) $(INC_RELEASE) -c main.c -o $(OBJDIR_RELEASE)/main.o
# ---------------------------------------------------------------------------
clean_release:
rm -f $(OBJ_RELEASE) $(OUT_RELEASE)
rm -f $(OBJ_RELEASE)
rm -rf $(OBJDIR_RELEASE)
# ---------------------------------------------------------------------------
.PHONY: before_release after_release clean_release