JV-ODE naval simulation

Blitz3D Forums/Blitz3D Userlibs/JV-ODE naval simulation

Santiworld(Posted 2008) [#1]
hi, sorry VIP3R if i make many questions...
this is another question about conceps of ode physics...

i make a ship, using the water sample..
and i move the ship using...

dbodyaddtorque and dbodyaddforce

my cuestion is, there is a best way or a correct method to make a motor ship sail on the wather?

thanks again...


VIP3R(Posted 2008) [#2]
One method is to apply force to the rear/center of the ship using the various force functions, taking into consideration the action of the rudder. Another method would be to add a large sphere to the rear of the ship (half submerged) with a hinge2 joint then rotate the sphere to drive/steer the boat, exactly like the front wheel of the car demos. You might need to give the sphere geom lots of friction for this to be effective (see the Demo-GeomFriction demo).

Also, experiment with different mass values for the water and the ship.

Feel free to ask any questions in the JV-ODE thread btw :)


Santiworld(Posted 2008) [#3]
i experiment all day with diferents ways to do this...

i use for the hull, a sphere, cube and cylinder...

with the cube i have the best results...
changing the friction, mass, and dimencions of cube, i can find diferentes way to move the ship...

but allways have a problem with this...

i dont know how tell to ode the fact of my hull, have less longitudinale resistanse less than lateral resistense...

so, if i have a small resistance, the ship go to the front nicely, but when i turn, the ship slide like if the water was ice...

but, if i give to much resistense to the hull, and incress the power, i have better result...


so, the question is, how is the best way to do the hull of the ship...
using a ode box, sphere, cilinder, a trimesh, or a combination of many of this....

thanks again, this days i learn many things about ode, i think ode is great, but is obvious, i'm rookie...

PD. if i use a box, when the ship turns have some problems with reality stability of the ship, that is the major problem when i use a box



i make an image to shop the option i try...


VIP3R(Posted 2008) [#4]
I've never tried making a boat/ship simulation, so it's difficult to suggest the best hull design. I wouldn't use a TriMesh, only use primitives. It should be possible to create an accurate hull with several primitives using Geom Offsets.

If you get stability problems, try adding a heavy body to the lower part of the ship to help stabilise it. Use a fixed joint to attach it to the ship body.

To help the sliding, try using both friction direction settings (see Friction Direction 1 demo), or increase the friction of the water body.


Santiworld(Posted 2008) [#5]
thanks Vip..
in few days i'm going to share all the things i've done with ode about boats and ships...

i can't find the way to set the longitudinal and lateral friction to an ode object.. i see the friction demo, the boxes with difenent values..

the only command i find to set friction is this "dGeomContactSetMu(ode\geom,count*0.5)"

i found in the manual, point "7.3.7 Contact" the things i could use, but i dont understand it yet...


about the hull, it floats perfectly on the water, but i found that it doesnt matter to dinamycs if the ship is going forward or side...

i think is because the ode must take all surface under water to make friction. maybe i can find the way to simulate hydrodinamic if i find the way to set friction direction...

thanks for the help, is good that you are available to discuss these topics...

im posting a modification of the water demo, to see the thing about friction...

im a naval technician, in school we calculate all data about ships using the cube of dimension of hull, frontal surface , to hydrodynamic friction, like cars...


; ###################################################################################################
; #										JV-ODE - Water Demo											#
; #									Code by Jim Williams (VIP3R)									#
; #								Devious Codeworks - Copyright © 2007								#
; ###################################################################################################

AppTitle "JV-ODE - Water Demo"

Include "JV-ODE.bb"

Graphics3D 800,600,0,2

Type ODEGeom
	Field body
	Field geom
	Field mesh
End Type

; ###################################################################################################

; ### Setup ODE

Global World=dWorldCreate()
Global Space=dHashSpaceCreate(0)
Global ContactGroup=dJointGroupCreate(0)

dWorldSetAutoDisableFlag(World,1)
dWorldSetGravity(World,0,-0.98,0)
dContactSetMode(dContactSlip1)
dContactSetMu(0.5)

; ### Create light

Global Light=CreateLight()

RotateEntity Light,45,-90,0
LightColor Light,255,255,255
AmbientLight 130,130,130

; ### Create camera

Global Camera=CreateCamera()
CameraClsColor Camera,0,0,0
CameraRange Camera,1,1000
PositionEntity Camera,0,45,-70
RotateEntity Camera,30,0,0

; ### Create plane

dCreatePlane(Space,0,1,0,0)

Plane=CreatePlane()

EntityAlpha Plane,0.8

PlaneTexture=CreateTexture(128,128,9)

ClsColor 0,200,80
Cls

Color 255,255,255

Rect 0,0,64,64,1
Rect 64,64,64,64,1

CopyRect 0,0,128,128,0,0,BackBuffer(),TextureBuffer(PlaneTexture)
ScaleTexture PlaneTexture,20,20
EntityTexture Plane,PlaneTexture,0,0

Mirror=CreateMirror()

; ###################################################################################################

; ### Create water

limite_agua =500

water_friction# = .09 ;  ### Water friction

ode.ODEGeom=New ODEGeom
ode\geom=dCreateBox(Space,limite_agua,15,limite_agua)
dGeomSetRotation(ode\geom,0,0,0)
dGeomSetPosition(ode\geom,0,7.5,0)
dGeomContactSetMode(ode\geom,dContactBounce+dContactSoftCFM)
dGeomContactSetBounce(ode\geom,0.6)		; ### Water bounce
dGeomContactSetSoftCFM(ode\geom,0.8)	; ### Water density
dGeomContactSetMu(ode\geom,water_friction)		
ode\mesh=CreateCube()
ScaleMesh ode\mesh,(limite_agua*.5),7.5,(limite_agua*.5)
EntityColor ode\mesh,0,100,200
EntityAlpha ode\mesh,0.7
EntityShininess ode\mesh,0.7



;Crear objeto de prueba	

	x_ancho# = 5
	x_alto#  = 3
	x_largo# = 20
	x_mass#  = 40
	x_friccion# =10
	
	
	ode.ODEGeom=New ODEGeom
	
	ode\body=dBodyCreate(World)
	dBodySetRotation(ode\body,19,45,0)
	dBodySetPosition(ode\body,0,10,00)
	mass=dMassCreate()
	dMassSetBoxTotal(mass,x_mass#,x_ancho,x_alto,x_largo)
	dBodySetMass(ode\body,mass)
	dMassDestroy(mass)
	
	dBodySetAutoDisableFlag(ode\body,0)
	
  ode\geom=dCreatebox(Space,x_ancho,x_alto,x_largo)
	CGeom=ode\geom
	dGeomSetBody(ode\geom,ode\body)
	dGeomContactSetMu(ode\geom,x_friccion#)
	
	ode\mesh=Createcube()
	scaleentity ode\mesh,x_ancho*.5,x_alto*.5,x_largo *.5
	
	EntityColor ode\mesh,250,100,0
	EntityAlpha ode\mesh,1
	EntityShininess ode\mesh,0.1

   vgiro# = a_timon# = velocidad# = potencia# = a_timon# = 0

; ###################################################################################################

While Not KeyHit(1)

	f#=.34    ; variable to incresse the factor to push
	
	f2#=4   ; factor to incress the turn
	
	
	fx#=sin(entityyaw#(ode\mesh))*potencia*f    ;find vector direction to push the ship
	fz#=-cos(entityyaw#(ode\mesh))*potencia*f
	
	dbodyaddtorque (ode\body,0,-a_timon * f2#,0)  ;apply to turn
	dbodyaddforce (ode\body,fx,0,fz)              ;apply to push the objet
	

   pointentity camera,ode\mesh
   

	if keydown(200) and potencia < 100 then potencia=potencia + 1
	if keydown(208) and potencia > -60 then potencia=potencia - 1
	if keydown(205) and a_timon >-60  then a_timon = a_timon - 1
	if keydown(203) and a_timon < 60  then a_timon = a_timon + 1

   	

	PTime=MilliSecs()
    If MilliSecs()-Timer>700
		Timer=MilliSecs()
		End If

	UpdateGeoms()

	dSpaceCollide(Space,World,ContactGroup)
	dWorldQuickStep(World,0.1)
	dJointGroupEmpty(ContactGroup)

	PhysicsTime#=MilliSecs()-PTime

	UpdateWorld

	RenderWorld

	Text 0,0,"JV-ODE Version "+dGetVersion()
	Text 0,15,"Physics Time:"+PhysicsTime

	text 0,40,"UP & DOWN to go forward."
	text 0,60,"LEFT & RIGHT to turn"

	Flip

Wend

dJointGroupDestroy(ContactGroup)
dSpaceDestroy(Space)
dWorldDestroy(World)
dCloseODE()

End


Function UpdateGeoms()

For ode.ODEGeom=Each ODEGeom
	RotateEntity ode\mesh,dGeomGetPitch#(ode\geom),dGeomGetYaw#(ode\geom),dGeomGetRoll#(ode\geom)
	PositionEntity ode\mesh,dGeomGetPositionX#(ode\geom),dGeomGetPositionY#(ode\geom),dGeomGetPositionZ#(ode\geom)
Next

End Function



i going to keep trying to make it work, gladly i'm going to share all things i learn about naval emulation with ode...

regards..
Santiago


VIP3R(Posted 2008) [#6]
Hmm, maybe the Friction Direction 1 demo probably wasn't the best suggestion as it only uses one friction setting for both directions.

To use both friction directions individually, add 'dContactMu2' and/or 'dContactFDir1' to the dContactSetMode() call in your simulation, then use...

dGeomContactSetMu(geom,mu#) and dGeomContactSetMu2(geom,mu#)

to set the friction for each direction and...

dGeomContactSetFDir1(geom,fdir1x#,fdir1y#,fdir1z#)

...if you want to set the orientation of the friction.


Santiworld(Posted 2008) [#7]
:) excelente, i going to try now... Thanks Vip3r!!!


Santiworld(Posted 2008) [#8]
hi, i working in this, i have another question..

i use dGeomContactSetFDir1(geom,fdir1x#,fdir1y#,fdir1z#)
but it seems that give friction in absolute axis x y z of the world...
and is not relative to the ode\body, so.. when i turn the ship, the fricction X continius in x word axis, and no turn with the ship... is no relative to object?..

saludos...


VIP3R(Posted 2008) [#9]
Yes that's correct behaviour.

From the ODE manual...

If set, take fdir1 as friction direction 1, otherwise automatically compute friction direction 1 to be perpendicular to the contact normal (in which case its resulting orientation is unpredictable).


To make it relative to the ship body, you need to constantly update 'fdir1x#,fdir1y#,fdir1z#' with the ships current rotation vector.

If your ship is heading along the Z axis and you want friction direction 1 to be used for forwards/backwards friction, then you would use 'fdir1x#=0.0 fdir1y#=0.0 fdir1z#=1.0', friction direction 2 would be along the X axis in this instance. Now if you turn the ship 90 degrees to the right, the fdir1 values would be 'fdir1x#=1.0 fdir1y#=0.0 fdir1z#=0.0'. Friction direction 1 is now along the X axis, and friction direction 2 is now along the Z axis.

There are some topics in the programming forums explaining the maths involved, don't forget that fdir1x/y/z have a range of 0.0 to 1.0 though.


Santiworld(Posted 2008) [#10]
hi vip...

i just want share the temporal solution i found to the lateral friction...

i had some problems, with the axis friction, becouse for one reason, the ship try to folow the axis heading, 0 90 180 280...
i think is because the friccion brake the ship in the axis with less force, and the other axis with more power, pass the fricttion vector more fast and the ship take a strange heading...


the temporari solution for lateral friction is...

1. i use the orientation of the ship.... (rumbo)
2. next, i take the real direction of the ship (direccion)
3. i convert the angles to (0-360)
4. i use (rumbo - direccion) * (velocidad) to set the fricciont of ode\geom
5. reaplace the (speed_object) to new position of ship, and orientation..

(speed_object) give the distance(speed) and real direction of ship...

make a objet, "

;this is to place the temp object over the ship 
positionentity speed_object, entityx#(ode\mesh,1),entityy#(ode\mesh,1),entityz#(ode\mesh,1)
	UpdateGeoms()
	positionentity speed_object,entityx#(speed_object),entityy#(ode\mesh,1),entityz#(speed_object)
   pointentity speed_object,ode\mesh

;this is to take the speed and heading and heading 2
rumbo# = entityyaw#(casco,1)
	if rumbo < 0 then rumbo = rumbo + 360
	
	direccion# = entityyaw(speed_object,1)-180
	if direccion# < 0 then direccion = direccion + 360
	
	diferencia# = abs(direccion - rumbo)
	if diferencia# > 180 then diferencia = 180 - (diferencia-180)
	
	diferencia2# = diferencia2# + diferencia# *.1
	diferencia2# = diferencia2# *.95
	
	xvelocidad# = xspeed# * 100
	
	diferencia3# = (diferencia2#*.1) * (.01+(xvelocidad *.03))


	dgeomcontactsetmu(ode\geom,diferencia3#)



when i learn more of ODE, maibe i find the solution of the friction and axis resulting...


thanks vip, i hope this simple solution it works for anyone else with the same problem...

saludos.. :)
santiago


VIP3R(Posted 2008) [#11]
You're welcome and thanks for the info :)