Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#1 Le 14/10/2007, à 18:55

L. Grondin

animation moteur rotatif à quatre chambres

Bonjour,

j'ai réussi à écrire un truc pour modèliser géométriquement une quasiturbine
(http://quasiturbine.promci.qc.ca/).

Nécessite bc, plotutils, imagemagick et mplayer.

On peut changer les paramètres a et b dans le code
pour modifier la taille du rotor et l' "exentricité" du stator.

Ca m'a pris tout le WE, mais j'suis assez fier du résultat  smile


#!/usr/bin/sh

export BC_LINE_LENGTH=1000
output="quasiturbine.avi"

bc -ql <<EOF |sh
pi=3.14159265359
a=0.3
b=0.4
c=4
define phi(arg) {
	return pi/4*(1+a*c(2*arg))
}
define r(arg) {
	return c(phi(arg))
}

reso=50
print "cat << FIN_STATOR > /tmp/stator\n"
print "1 0 ", r(0), " 0\n"
for(k=0;k<4*reso;k++) {
	theta = pi/2*k/reso
	r = r(theta)-b/2
	dr = a*pi/2*s(2*theta)*s(phi(theta))
	n = sqrt( r^2 + dr^2 )
	print r*(1+b/2/n)*c(theta)+b/2*dr/n*s(theta), " "
       	print r*(1+b/2/n)*s(theta)-b/2*dr/n*c(theta), "\n"
}
print c(theta), " ", r*(1+b/2/n)*s(theta)-b/2*dr/n*c(theta), "\n"
while(k--) {
	theta = pi/2*k/reso
	print c(theta), " ", s(theta), "\n"
}
print "FIN_STATOR\n"

reso=100
for(k=0;k<reso;k++) {
	print "cat << FIN_ROTOR > /tmp/rotor\n"
	for(j=0;j<c;j++) {
		theta = pi/4+pi/2*(j+k/reso)
		cos = c(theta)
		sin = s(theta)
		x1 = (r(theta)-b/2)*cos
		y1 = (r(theta)-b/2)*sin
		x2 =  -(r(theta+pi/2)-b/2)*sin
		y2 =  (r(theta+pi/2)-b/2)*cos

		for(i=0;i<reso;i++) {
			gamma = theta - phi(theta) - (pi - pi/6/2) + (2*pi - pi/6)*i/reso
			print x1 + b/4*c(gamma), " ", y1 + b/4*s(gamma), "\n"
		}
		for(i=0;i<reso;i++) {
			gamma = theta - phi(theta) - 3*pi/4 + pi*i/reso
			print x2 + b/2*c(pi+gamma), " ", y2 + b/2*s(pi+gamma), "\n"
		}
		for(i=0;i<reso;i++) {
			gamma = theta - phi(theta) - 3*pi/4 + pi - 3*pi/2*i/reso
			print x2 + b/4*c(pi+gamma), " ", y2 + b/4*s(pi+gamma), "\n"
		}
		print x2 + b/2*c(pi+gamma), " ", y2 + b/2*s(pi+gamma), "\n"
		print x1 + b/4*c(theta - phi(theta) - (pi - pi/6/2)), " ", y1 + b/4*s(theta - phi(theta) - (pi - pi/6/2)), "\n"
		print "\n"
	}
	print "FIN_ROTOR\n"
	print "graph -T png -g 0 -q .4  -x -1 1 -y -1 1 --blankout 0.0 /tmp/stator -C "
	print "--reposition 0 0 1 -q .2 /tmp/rotor "
	print "|convert - img-", reso+k, ".jpg"
	print "\n"
}
quit
EOF

mencoder "mf://img-*.jpg" -mf fps=45:type=jpeg -ovc copy -oac copy -o $output
rm -f *.jpg /tmp/stator /tmp/rotor
mplayer $output -loop 0

#2 Le 20/10/2007, à 21:12

olleg

Re : animation moteur rotatif à quatre chambres

C'est enorme ce que tu as fait. félicitation.
Bel exemple de code.


MSI S260, Pentium M740, 1,5Go de RAM, 60Go de DD. Ubuntu 9.04
Zotac geforce 9300-itx wifi + SG05 + Intel E8400 + 4Go de RAM. Ubuntu 9.04

Hors ligne

#3 Le 28/10/2007, à 13:08

eric42

Re : animation moteur rotatif à quatre chambres

Bonjour,

J'ai du rater quelque chose mais je n'arrive pas à éxécuter ton script.

J'ai copier le code que j'ai collé dans un fichier texte que j'ai enfin rendu exécutable.

Rien ne se passe.

Merci d'avance.

Eric

#4 Le 29/10/2007, à 11:21

jeremix

Re : animation moteur rotatif à quatre chambres

Salut, idem que eric42.
Un p'tit coup de pouce svp big_smile


ubuntucounter user 8236

Hors ligne

#5 Le 29/10/2007, à 11:28

eric42

Re : animation moteur rotatif à quatre chambres

En collant le code directement dansun terminal voilà le résultat :

sh: graph: not found
convert: missing an image filename `img-100.jpg'.
sh: graph: not found
convert: missing an image filename `img-101.jpg'.
sh: graph: not found
sh: graph: not found
convert: missing an image filename `img-199.jpg'.
eric@eric-desktop:~$ 
eric@eric-desktop:~$ mencoder "mf://img-*.jpg" -mf fps=45:type=jpeg -ovc copy -oac copy -o $output
MEncoder 2:1.0~rc1-0ubuntu13 (C) 2000-2006 MPlayer Team
CPU: Intel(R) Pentium(R) 4 CPU 2.93GHz (Family: 15, Model: 4, Stepping: 1)
CPUflags: Type: 15 MMX: 1 MMX2: 1 3DNow: 0 3DNow2: 0 SSE: 1 SSE2: 1
Compiled with runtime CPU detection.
success: format: 16  data: 0x0 - 0x0
MF file format detected.
[mf] search expr: img-*.jpg
============ Sorry, this file format is not recognized/supported =============
=== If this file is an AVI, ASF or MPEG stream, please contact the author! ===
Cannot open demuxer.

Exiting...
eric@eric-desktop:~$ rm -f *.jpg /tmp/stator /tmp/rotor
eric@eric-desktop:~$ mplayer $output -loop 0

Je vais vérifier que les programmes nécessaires soient correctement installés et je vous tiens au courant.

Eric

#6 Le 04/11/2007, à 13:42

L. Grondin

Re : animation moteur rotatif à quatre chambres

Bonjour,

ravi de voir que ce truc interesse du monde.

l'erreur "graph : not found" signifie que le package plotutils n'est pas installé.

sinon dans l'entête il vaut mieux mettre #!/usr/bin/bash plutôt que #!/usr/bin/sh.

Normalement il suffit de copier dans un fichier texte "qt.sh" et de taper

$ bash qt.sh

attention à ce que lors du copier/coller le navigateur n'ajoute pas des "> " à chaque début
de ligne..

le calcul et la création de l'anim prend environ 20 secondes.
Il y a quelques erreurs dans le code que j'ai envoyé :
tout n'est géométriquement pas tout à fait exact.

Enfin j'ai persévéré, j'ai corrigé quelques erreurs dans le code
et surtout j'ai écrit la même chose en mieux et avec python pour
faire un modèle 3D :

http://picasaweb.google.fr/grondilu/quasiturbine

je vais essayer d'animer la version 3D maintenant...

#7 Le 04/11/2007, à 14:26

eric42

Re : animation moteur rotatif à quatre chambres

Bonjour,

C'est vrai qu'avec les bonnes dépendances celà fonctionne.

Très intéressant ton travail,  je me pose quelques questions les forces ne vont elles pas s'annuler ?

L'axe principal permettant de transmettre le mouvement rotatif est composé des quatre axes des bielles ?

Les lobbys ont complètement ruiné la créativité" et l'invitivité ...

Merci de ton complément d'informations.

Eric

#8 Le 04/11/2007, à 19:55

L. Grondin

Re : animation moteur rotatif à quatre chambres

Salut,

en parlant de forces qui s'annulent,
je suppose que tu te demandes si la force crée lors de la détente peut
l'emporter sur celle nécessaire à la compression.  Bah à priori oui puisque
la détente est en fait une explosion où l'énergie chimique du combustible
entre en jeu... Sans parler du fait que le système peut fonctionner à l'air comprimé,
auquel cas il n'y a pas de phase de compression.

Mais bon la page de wikipedia décrit tout ça très bien :
http://fr.wikipedia.org/wiki/Quasiturbine
Les liens qui s'y trouvent dirigent aussi vers des vidéos où on voit des prototypes fonctionner
à l'air comprimé (d'après wikipedia à ce jour aucun prototype n'a jamais
été montré en fonctionnant comme un moteur à explosion)

Concernant la transmission du mouvement,
c'est une vrai question qui m'a donné du fil à retordre pour faire un modèle 3D.
Les concepteurs initiaux préconisent l'usage de deux manivelles reliées
aux centres des faces du losange.  Ne sachant pas ce qu'est exactement
une "manivelle", j'ai préféré ôpter pour un arbre relié aux sommets par des pivots
glissants.

Voici mon code python pour mon modèle 3D sous Blender
(un peu long certes, il doit y avoir moyen de faire plus court...) :

import Blender

from Blender import Scene, Mathutils
from Blender.Mathutils import *

from math import *

scn=Scene.getCurrent()

for ob in scn.objects:
	if ob.type == 'Mesh':
		scn.unlink(ob)

Blender.Redraw()


# PARAMETRES

a=.3 # "exentricit\'e" du stator
b=.2 # rayon des cylindres de contact
N=200 # r\'esolution angulaire

global_angle=0 # dephasage du moteur



# FONCTIONS

def phi(arg):  # angle au sommet du losange
	return pi/4*(1+a*cos(2*arg))

def phip(arg): # deriv\'ee premi\`ere de phi
	return -a*pi/2*sin(2*arg)

def r(arg): # \'equation polaire des centres des cylindres
	return (1-b)*cos(phi(arg))

def rp(arg): # deriv\'ee premi\`ere de r
	return -(1-b)*phip(arg)*sin(phi(arg))




# STATOR

angles=[k*2*pi/N for k in range(N)]
statorInterieur2D=[]
statorExterieur2D=[]

for theta in angles:
	n=sqrt(r(theta)**2+rp(theta)**2)
	statorInterieur2D+=[[cos(theta)*r(theta)*(1+b/n)+b*rp(theta)/n*sin(theta), \
		sin(theta)*r(theta)*(1+b/n)-b*rp(theta)/n*cos(theta)]]
	statorExterieur2D+=[[cos(theta), sin(theta)]]

verts=[]
for k in range(N):
	verts+=[ statorInterieur2D[k]+[0],\
		 statorInterieur2D[k]+[1],\
		 statorExterieur2D[k]+[1],\
		 statorExterieur2D[k]+[0]]

faces=[]
for k in range(0,4*N,4):
	faces+=[ [k, (k-4)%(4*N), (k-3)%(4*N), k+1], \
	         [k, (k-4)%(4*N), (k-1)%(4*N), k+3], \
		 [k+3, (k-1)%(4*N), (k-2)%(4*N), k+2], \
		 [k+1, k+2, (k-2)%(4*N), (k-3)%(4*N)] ]

	
me=Blender.Mesh.New('stator')

me.verts.extend(verts)
me.faces.extend(faces)

stator=Blender.Scene.GetCurrent().objects.new(me, 'stator')



# ROTOR

rotor=[]
alpha=pi/3

for n in range(4):

	repere=[]
	
	verts=[]
	faces=[]
	
	i=0

	za, zb = .025 + n*.25, .225 + n*.25
	
	theta=-pi+alpha/2
	for z in 0, 1, za, zb:
		verts.append([b/2*cos(theta), b/2*sin(theta),z])
		i+=1
	
	theta=-pi+alpha/2
	while(theta<pi+alpha/2):
		if theta<=pi-alpha/2:
			for z in 0, 1, za, zb:
				verts.append([b/2*cos(theta), b/2*sin(theta),z])
				i+=1
			faces.append([i-8,i-6,i-2,i-4])
			faces.append([i-5,i-1,i-3,i-7])
			faces.append([3,i-1,i-5])
			faces.append([2,i-2,i-6])
			faces.append([1,i-3,i-7])
			faces.append([0,i-4,i-8])
		elif theta<pi:
			if len(repere)==0:
				repere.append(i-4)
				theta_backup=theta-2*pi/N
			for z in za, zb:
				verts.append([b/2*cos(theta), b/2*sin(theta),z])
				i+=1
			faces.append([3,i-1,i-3])
			faces.append([2,i-2,i-4])
			faces.append([i-1,i-2,i-4,i-3])
		else:
			if len(repere)==1:
				theta=pi
				repere.append(i)
			for z in za, zb:
				verts.append([b/2*cos(theta), b/2*sin(theta),z])
				i+=1
			faces.append([3,i-1,i-3])
			faces.append([2,i-2,i-4])
		theta+=2*pi/N
	
	theta=theta_backup
	for z in 0, 1:
		verts.append([b*cos(theta),b*sin(theta),z])
		i+=1
	faces.append([repere[0],repere[0]+1,i-1,i-2])
	
	# repère 2
	repere.append(i-2)
	
		
	for z in 0, 1:
		verts.append([b*cos(theta)-b*(1-sin(theta))*sin(theta)/cos(theta),b,z])
		i+=1
	faces.append([i-1,i-2,i-4,i-3])
	
	for z in 0, 1:
		verts.append([b-1,b,z])
		i+=1
	faces.append([i-1,i-2,i-4,i-3])
	
	theta=pi/2
	while theta < 2*pi-alpha/2-pi/2*(1+a):
		for z in 0,1:
			verts.append([b-1+b*cos(theta),b*sin(theta),z])
			i+=1
		faces.append([i-1,i-2,i-4,i-3])
		theta+=2*pi/N
	
	# repère 3
	repere.append(i-2)
	
	theta-=2*pi/N
	for z in 0, 1:
		verts.append([b-1+b/2*cos(theta),b/2*sin(theta),z])
		i+=1
	faces.append([i-1,i-2,i-4,i-3])
	
	
	while theta > 0:
		for z in 0, 1:
			verts.append([b-1+b/2*cos(theta), b/2*sin(theta),z])
			i+=1
		faces.append([i-1,i-2,i-4,i-3])
		theta-=2*pi/N
	
	za, zb = .025 + (n+1)%4*.25, .225 + (n+1)%4*.25
	
	theta=0
	for z in 0, 1, za, zb:
		verts.append([b-1+b/2*cos(theta), b/2*sin(theta),z])
		i+=1
	theta-=2*pi/N
	faces.append([i-4,i-3,i-5,i-6])
	
	# repère 4
	repere.append(i-4)
	
	thetamax = max(alpha/2-pi/2*(1-a),-pi*a)
	while theta > thetamax:
		for z in 0, 1, za, zb:
			verts.append([b-1+b/2*cos(theta), b/2*sin(theta),z])
			i+=1
		theta-=2*pi/N
		faces.append([i-4,i-2,i-6,i-8])
		faces.append([i-1,i-3,i-7,i-5])
	
	theta+=2*pi/N
	for z in 0, 1, za, zb:
		verts.append([b-1+b*cos(theta), b*sin(theta),z])
		i+=1
	faces.append([i-4,i-2,i-6,i-8])
	faces.append([i-1,i-3,i-7,i-5])
				
	# repère 5
	repere.append(i-4)
	
	for z in 0,1,za, zb:
		verts.append([3*b/2-1+b/2*sin(alpha/2)/tan(pi/4*(1-a)),-b/2*sin(alpha/2),z])
		i+=1
	for j in range(4):
		faces.append([i-8+j,i-12+j,i-4+j])
		k=i-12+j
		while k>repere[4]+j:
			faces.append([k,k-4,i-4+j])
			k-=4
	faces.append([i-4,i-2,i-6,i-8])
	faces.append([i-1,i-3,i-7,i-5])
	faces.append([repere[4]+2,repere[4]+3,i-1,i-2])
	
	za, zb = .025 + n*.25, .225 + n*.25
	
	for z in za, zb:
		verts.append([-b/2*(1+sin(alpha/2)/tan(pi/4*(1-a))),-b/2*sin(alpha/2),z])
		i+=1
	faces.append([i-1,i-2,repere[1],repere[1]+1])
	
	j=repere[1]+2
	while (verts[j][1]<verts[j-2][1]):
		faces.append([j,j-2,i-2])
		faces.append([j+1,j-1,i-1])
		j+=2
	faces.append([j-2,2,i-2])
	faces.append([j-1,3,i-1])

	if n<3:	
		faces.append([i-2,2,0,i-6])
		faces.append([i-6,i-4,i-1,i-2])
		faces.append([i-4,i-3,3,i-1])
		faces.append([3,i-3,i-5,1])
	else:
		faces.append([i-1,3,1,i-5])
		faces.append([i-3,i-2,i-1,i-5])
		faces.append([i-3,i-4,2,i-2])
		faces.append([i-4,i-6,0,2])
	
	for k in 0, 1:
		faces.append([k,repere[0]+k,repere[2]+k, repere[-1]+4+k])
		faces.append([repere[4]+k,repere[2]+2+k,repere[2]+k, repere[-1]+4+k])
	
	k=0
	while repere[3]-k>=repere[2]+6:
		faces.append([repere[3]-k+1,repere[3]-k-1,repere[3]+k+7,repere[3]+k+5])
		faces.append([repere[3]-k,repere[3]-k-2,repere[3]+k+6,repere[3]+k+4])
		k+=2
	
	k1=repere[3]+k
	k2=repere[4]
	while k1+4<k2-2:
		faces.append([k1+4, k1+2, repere[2]+6])
		faces.append([k1+5, k1+3, repere[2]+7])
		k1+=2
		faces.append([k2, k2-2, repere[2]+2])
		faces.append([k2+1, k2-1, repere[2]+3])
		k2-=2
	
	for k in 0, 1:
		if k1+4<>k2-2:
			faces.append([k1+4+k,k2-2+k,repere[2]+6+k,repere[2]+2+k])
		else:
			faces.append([k1+4+k,k1+2+k,repere[2]+6+k,repere[2]+2+k])
			faces.append([k2+k,k2-2+k,repere[2]+6+k,repere[2]+2+k])
	
	theta=n*pi/2+global_angle
	R = RotationMatrix(-360*(theta-phi(theta))/(2*pi),4,'z')
	T = TranslationMatrix(Vector([r(theta)*cos(theta), r(theta)*sin(theta), 0]))
	
	Verts=[]
	for v in verts:
		Verts.append(Vector(R*Vector(v)*T))
		
	me=Blender.Mesh.New('rotor_' +str(n))
	
	me.verts.extend(Verts)
	me.faces.extend(faces)
	
	rotor.append(Blender.Scene.GetCurrent().objects.new(me, 'rotor_'+ str(n)))
	
	za, zb = .025 + n*.25, .225 + n*.25
	
	i=0
	verts=[]
	faces=[]
	theta=-pi+pi/4*(1-a)
	for z in za, zb:
		verts.append([b/2*cos(theta), b/2*sin(theta),z])
		i+=1
	
	theta=-pi+pi/4*(1-a)
	while(theta<pi-pi/4*(1-a)):
		for z in za, zb:
			verts.append([b/2*cos(theta), b/2*sin(theta),z])
			i+=1
		faces.append([i-3,i-1,i-2,i-4])
		faces.append([1,i-1,i-3])
		faces.append([0,i-2,i-4])
		theta+=2*pi/N

	theta=pi-pi/4*(1-a)
	for z in za, zb:
		verts.append([b/2*cos(theta), b/2*sin(theta),z])
		i+=1
	faces.append([i-3,i-1,i-2,i-4])
	faces.append([1,i-1,i-3])
	faces.append([0,i-2,i-4])
	
	for z in za, zb:
		verts.append([b-2*(1-b)*cos(pi/4*(1+a)),b/2*sin(theta),z])
		verts.append([b-2*(1-b)*cos(pi/4*(1+a)),-b/2*sin(theta),z])
		i+=2
	
	faces.append([i-1,i-2,i-4,i-3])
	faces.append([i-1,i-3,0,1])
	faces.append([i-1,i-2,i-5,1])
	faces.append([i-5,i-6,i-4,i-2])
	faces.append([i-4,i-3,0,i-6])
	
	theta=n*pi/2+global_angle
	R = RotationMatrix(-360*theta/(2*pi),4,'z')
	T = TranslationMatrix(Vector([r(theta)*cos(theta), r(theta)*sin(theta), 0]))

	Verts=[]
	for v in verts:
		Verts.append(Vector(R*Vector(v)*T))
		
	me=Blender.Mesh.New('axe_' +str(n))
	
	me.verts.extend(Verts)
	me.faces.extend(faces)
	
	rotor.append(Blender.Scene.GetCurrent().objects.new(me, 'axe_'+ str(n)))
		
	i=0
	verts=[]
	faces=[]
	
	L=((1-b)*cos(pi/4*(1+a))-b)
	l=b/2*sin(pi/4*(1-a))
	
	for x in -L, L:
		for y in -b/2, -l, l, b/2:
			for z in za-.0125, za, zb, zb +.0125:
				verts.append([x,y,z])
				i+=1
	faces.append([0,16,19,3])
	faces.append([3,19,31,15])				
	faces.append([0,12,28,16])
	faces.append([12,28,31,15])

	faces.append([5,21,22,6])
	faces.append([9,25,26,10])
	faces.append([5,9,25,21])
	faces.append([22,26,10,6])				

	for k in 0, 16:
		faces.append([0+k,3+k,6+k,5+k])
		faces.append([0+k,12+k,9+k,5+k])
		faces.append([12+k,15+k,10+k,9+k])
		faces.append([15+k,3+k,6+k,10+k])

	Verts=[]
	for v in verts:
		Verts.append(Vector(R*Vector(v)))
		
	me=Blender.Mesh.New('centre_' +str(n))
	
	me.verts.extend(Verts)
	me.faces.extend(faces)
	
	rotor.append(Blender.Scene.GetCurrent().objects.new(me, 'centre_'+ str(n)))
			
Blender.Redraw()

#9 Le 04/11/2007, à 20:45

eric42

Re : animation moteur rotatif à quatre chambres

Bonjour,

Merci de ces informations complémentaires.

Je reste vraiment pensif sur le moyen de transmettre le mouvement rotatif à un arbre externe.

C'est super ce concept.

Eric

Dernière modification par eric42 (Le 04/11/2007, à 20:46)

#10 Le 08/11/2007, à 07:17

Brunod

Re : animation moteur rotatif à quatre chambres

Salut, Je pense qu'une "manivelle" est un autre terme pour désigner un villebrequin mais qui peut-être n'aurait qu'un seul pallier.
Brunod


Windows est un système d'exploitation de l'homme par l'ordinateur. Linux, c'est le contraire...
39 pc linux convertis

Hors ligne