Simuv3 update
Christos Dimitrakakis <[email protected]> Sun, 12 Jul 2009 11:08:35 +0200
| Newsgroups | gmane.games.torcs.devel |
|---|---|
| Message-ID | <[email protected]> |
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Simuv3 update, in torcs cvs. 1. Discovered that corner velocities are not correctly calculated 2. Stabilised CollideZ() code - removed corner velocity from calculation of reaction forces. TODO 1. Find out the correct corner velocity calculation. This currently works fine in an octave code which I made a few months ago, which calculates quaternion derivatives. The torcs code, in car.cpp::SimCarUpdateCornerPos(), uses a weird implementation. For reference, I attach the working octave code if somebody wants to try and implement it for TORCS. 2. Unify the car collision code with the border collision. 3. Test test test. -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.6 (GNU/Linux) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org iD8DBQFKWagTyBv6kELa61sRAvJoAJ4r6VNQ2WcohXAj8qkeVtWa0o0s+QCfdMFF 7LxW9AT2l1TlmjIYWwDeORM= =jW0p -----END PGP SIGNATURE----- ------------------------------------------------------------------------------ Enter the BlackBerry Developer Challenge This is your chance to win up to $100,000 in prizes! For a limited time, vendors submitting new applications to BlackBerry App World(TM) will have the opportunity to enter the BlackBerry Developer Challenge. See full prize details at: http://p.sf.net/sfu/Challenge _______________________________________________ Torcs-devel mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/torcs-devel
collide.m
(text/plain, 4.8 KB)
## -*- Mode: octave -*-
1;
init_angle = 0;#randn;
q = quaternion(rand(3,1), init_angle);
w = rand(3,1)*20;
s=[3, 3, 3]';
x = [0, -5, 3]';
u = [0, rand*20, rand*5]';
dt=0.01;
m=4;
Im=[3,3,3]';
E_kinetic = m*u'*u/2;
E_dynamic = m*9.81*x(3);
E_rotational = w'*w;
E = E_dynamic + E_kinetic + E_rotational
for t=1:1000
## x - position vector
## q - rotation quaternion
## u - velocity vector
## w - moment of inertia vector
## m - mass
## Im - rotational inertia
## s - size of the polyhedron
#function polyhedral_collide (x, q, u, w, m, Im, s)
## object has eight corners
c = zeros(8, 3);
length = s(1);
width = s(2);
height = s(3);
## Front Aft Left Right Top Bottom
c(1,:) = [+length/2, -width/2, +height/2]; # FLT
c(2,:) = [+length/2, +width/2, +height/2]; # FRT
c(3,:) = [-length/2, -width/2, +height/2]; # ALT
c(4,:) = [-length/2, +width/2, +height/2]; # ART
c(5,:) = [+length/2, -width/2, -height/2]; # FLT
c(6,:) = [+length/2, +width/2, -height/2]; # FRT
c(7,:) = [-length/2, -width/2, -height/2]; # ALT
c(8,:) = [-length/2, +width/2, -height/2]; # ART
c = c'; ## local points
qc = c; ## global points
## transform all points to global frame
for i=1:8
qc(:,i) = x + qtransv(c(:,i), q);
end
dheight = 0;
collision_i = [];
for i=1:8
dci = qc(3, i);
if (dci < dheight)
collision_i = [collision_i, i];
dheight = dci;
end
end
F = [0 0 -9.81*m]';
M = [0 0 0]';
E_prev = E;
## and get Q derivative
dq = qderivmat(w./Im)*q';
q_inv = qinv(q);
## trying to get the rotation-only velocity of each point
q_delta = q + 0.01*dq';
q_delta /= sum(q_delta.*q_delta);
if (1)
if (size(collision_i) > 0 && u(3) < 0)
for ci = collision_i
## the force required to stop the cube's center of mass
N_global = -u(3)*m/dt;
## transform from global to local
N = qtransv([0 0 N_global], q_inv);
## force on the axis... hm.. irrelevant?
Fx = N(1);
Fy = N(2);
Fz = N(3);
d = c(:, ci);
## rotation-only velocity of each point
#ru = qtransv(d, dq);#q*0.01);
## the velocity of each point in the global fra
## rotation-only velocity of each point
##ru = qtransv(d, dq);
## the velocity of each point in the global frame
cu_global = u + (qtransv(d, q_delta) - qtransv(d,q))/0.1;
## the velocity of each point in the rotating frame
cu = qtransv(cu_global, q_inv);
## calculate friction globally
Friction_global = zeros(3,1);
mu = 0.1;
Friction_global(1) -= mu*abs(N_global)*cu_global(1);
Friction_global(2) -= mu*abs(N_global)*cu_global(2);
## z-axis speed is not important here.
Friction_local = qtransv(Friction_global, q_inv);
Fx += Friction_local(1);
Fy += Friction_local(2);
Fz += Friction_local(3);
M(1) -= -Fz*d(2) + Fy*d(3);
M(2) -= +Fz*d(1) - Fx*d(3);
M(3) -= +Fx*d(2) - Fy*d(1);
F_local = [Fx Fy Fz]';
F += qtransv(F_local, q);
endfor
x -= [0 0 dheight+u(3)*dt]';
endif
else
collision_i =1;
Fu = 1000;
F(3) += Fu;
M += c(:,collision_i)*Fu;
##u(3) = 0;
endif
if (mod(t-1, 5)==0)
hold off;
plot3(qc(1,:), qc(2,:), qc(3,:), '@-');
hold on;
plot3([x(1), x(1)+F(1)/100], [x(2), x(2)+F(2)/100], [x(3), x(3)+F(3)/100],'1-')
view(75, 10);
axis([-20, 20, -20, 20, -1, 40], "manual", "square");
if (0) #size(collision_i) > 0)
for ci = 1:8 #collision_i
d = c(:, ci);
## the velocity of each point in the global frame
cu_global = (qtransv(d, q_delta) - qtransv(d,q))/0.1;
plot3([qc(1,ci), qc(1,ci)+cu_global(1)], [qc(2,ci), qc(2,ci)+cu_global(2)], [qc(3,ci), qc(3,ci)+cu_global(3)],'4-')
endfor
endif
view(75, 10);
axis([-20, 20, -20, 20, -1, 40], "manual", "square");
endif
#if (size(collision_i) > 0)
# sleep(0.1);
#endif
#g = [0 0 -9.81]' + F/m;
#g = [0 0 -9.81]' + F/m;
#M, dheight
w += M./Im *dt;
u += F/m*dt;
x += u*dt;
E_kinetic = m*u'*u/2;
E_dynamic = m*9.81*x(3);
E_rotational = w'*diag(Im)*w;
E = E_dynamic + E_kinetic + E_rotational;
##E_prev *=0.999;
if (E > 1.01*E_prev)
E_diff = E - E_prev;
E_movement = E_kinetic + E_rotational;
scale = E_diff / E_movement;
E_movement = (1 - scale)*E_movement;
E_kinetic *= (1 - scale);
E_rotational *= (1 - scale);
if (scale>=1)
u *= 0;
w *= 0;
else
u*=sqrt(1-scale);
w*=sqrt(1-scale);
endif
E = E_dynamic + E_kinetic + E_rotational;
printf ("E_diff: %f -- (%f) --> %f\n", E_diff, scale, E-E_prev);
endif
fflush(stdout);
## translate rotational inertia to rotation
q += dq'*dt;
q = q / sum(q.^2);
sleep(0);
endfor
#endfunction