Skip to content

Commit e68dc8d

Browse files
committed
Mecanum Wheels
1 parent a69befe commit e68dc8d

4 files changed

Lines changed: 107 additions & 29 deletions

File tree

Scene.cfg

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
TestTexture.test
1+
RobotFactoryLite2021

Viewer.lfm

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
object FViewer: TFViewer
2-
Left = 370
2+
Left = 392
33
Height = 524
4-
Top = 170
4+
Top = 132
55
Width = 757
66
Caption = 'SimTwo View'
77
ClientHeight = 524
@@ -1149,10 +1149,13 @@ object FViewer: TFViewer
11491149
Material.FrontProperties.Specular.Green = 0
11501150
Material.FrontProperties.Specular.Blue = 0
11511151
Material.FrontProperties.Specular.Alpha = 1
1152-
Material.Texture.EnvColor.Red = 0
1152+
Material.Texture.EnvColor.Red = 200
11531153
Material.Texture.EnvColor.Green = 0
11541154
Material.Texture.EnvColor.Blue = 0
1155-
Material.Texture.EnvColor.Alpha = 0
1155+
Material.Texture.EnvColor.Alpha = 200
1156+
Material.Texture.EnvColor.Color = {
1157+
00004843000000000000000000004843
1158+
}
11561159
Material.Texture.BorderColor.Red = 0
11571160
Material.Texture.BorderColor.Green = 0
11581161
Material.Texture.BorderColor.Blue = 0
@@ -1813,7 +1816,6 @@ object FViewer: TFViewer
18131816
MaxDeltaTime = 0
18141817
MinDeltaTime = 0
18151818
FixedDeltaTime = 0.0166666666666667
1816-
Mode = cmApplicationIdle
18171819
SleepLength = 1
18181820
OnProgress = GLCadencerProgress
18191821
left = 196
@@ -1924,7 +1926,7 @@ object FViewer: TFViewer
19241926
top = 164
19251927
end
19261928
object TimerCadencer: TTimer
1927-
Interval = 10
1929+
Interval = 5
19281930
OnTimer = TimerCadencerTimer
19291931
left = 76
19301932
top = 132
@@ -1939,10 +1941,22 @@ object FViewer: TFViewer
19391941
Font.CharSet = ANSI_CHARSET
19401942
Font.Color = clWhite
19411943
Font.Height = -27
1942-
Font.Name = 'Liberation Sans'
1943-
Font.Pitch = fpVariable
1944+
Font.Name = 'Liberation Mono'
1945+
Font.Pitch = fpFixed
19441946
Font.Quality = fqDraft
19451947
left = 308
19461948
top = 36
19471949
end
1950+
object GLBitmapFont: TGLBitmapFont
1951+
GlyphsIntervalX = 0
1952+
GlyphsIntervalY = 0
1953+
Ranges = <
1954+
item
1955+
StartASCII = #0
1956+
StopASCII = #0
1957+
StartGlyphIdx = 0
1958+
end>
1959+
left = 295
1960+
top = 124
1961+
end
19481962
end

Viewer.pas

Lines changed: 84 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,7 @@ TWorld_ODE = class
208208
{ TFViewer }
209209

210210
TFViewer = class(TForm)
211+
GLBitmapFont: TGLBitmapFont;
211212
GLScene: TGLScene;
212213
GLCadencer: TGLCadencer;
213214
GLSceneViewer: TGLSceneViewer;
@@ -443,10 +444,12 @@ procedure nearCallback (data : pointer; o1, o2 : PdxGeom); cdecl;
443444
if (o1.data <> nil) and (TSolid(o1.data).kind in [skOmniWheel, skOmniSurface, skMecanumWheel_L, skMecanumWheel_R]) then begin
444445
n_mode := n_mode or cardinal(dContactMu2 or dContactFDir1);
445446
if TSolid(o1.data).kind = skOmniWheel then begin
446-
dBodyVectorToWorld(b1, 0, 0, 1, n_fdir1);
447-
tmp := n_mu2;
448-
n_mu2 := n_mu;
449-
n_mu := tmp;
447+
//dBodyVectorToWorld(b1, 0, 0, 1, n_fdir1);
448+
//tmp := n_mu2;
449+
//n_mu2 := n_mu;
450+
//n_mu := tmp;
451+
dBodyVectorToWorld(b1, 0, 0, 1, aux_v1);
452+
n_fdir1 := Vector3Cross(contact[0].geom.normal, aux_v1);
450453
end else if TSolid(o1.data).kind = skMecanumWheel_L then begin
451454
//dBodyVectorToWorld(b1, 0, 0, 1, n_fdir1);
452455
dBodyVectorToWorld(b1, 0, 0, 0.707106781186547, aux_v1); // 1/sqrt(2)
@@ -464,10 +467,12 @@ procedure nearCallback (data : pointer; o1, o2 : PdxGeom); cdecl;
464467
n_mode := n_mode or cardinal(dContactMu2 or dContactFDir1);
465468
//dBodyVectorToWorld(b2, 0, 0, 1, n_fdir1);
466469
if TSolid(o2.data).kind = skOmniWheel then begin
467-
dBodyVectorToWorld(b2, 0, 0, 1, n_fdir1);
468-
tmp := n_mu2;
469-
n_mu2 := n_mu;
470-
n_mu := tmp; //0.001;
470+
//dBodyVectorToWorld(b2, 0, 0, 1, n_fdir1);
471+
//tmp := n_mu2;
472+
//n_mu2 := n_mu;
473+
//n_mu := tmp; //0.001;
474+
dBodyVectorToWorld(b2, 0, 0, 1, aux_v1);
475+
n_fdir1 := Vector3Cross(contact[0].geom.normal, aux_v1);
471476
end else if TSolid(o2.data).kind = skMecanumWheel_L then begin
472477
//dBodyVectorToWorld(b2, 0, 0, 1, n_fdir1);
473478
dBodyVectorToWorld(b2, 0, 0, 0.707106781186547, aux_v1); // 1/sqrt(2)
@@ -2466,8 +2471,14 @@ procedure TWorld_ODE.LoadObstaclesFromXML(XMLFile: string; OffsetDef: TSolidDef;
24662471
Vec: TDVector3;
24672472
NewObstacle: TSolid;
24682473

2474+
hasCanvas: boolean;
2475+
CanvasWidth, CanvasHeigth: integer;
2476+
24692477
Surf: TdSurfaceParameters; //TOD=: unify with solids
24702478
begin
2479+
hasCanvas := false;
2480+
CanvasWidth := 256; CanvasHeigth := 256;
2481+
24712482
XML := LoadXML(XMLFile, XMLErrors);
24722483
if XML = nil then exit;
24732484

@@ -2514,6 +2525,11 @@ procedure TWorld_ODE.LoadObstaclesFromXML(XMLFile: string; OffsetDef: TSolidDef;
25142525
Surf.bounce := GetNodeAttrRealParse(prop, 'bounce', Surf.bounce, Parser);
25152526
Surf.bounce_vel := GetNodeAttrRealParse(prop, 'bounce_tresh', Surf.bounce_vel, Parser);
25162527
end;
2528+
if prop.NodeName = 'canvas' then begin
2529+
hasCanvas := true;
2530+
CanvasWidth := round(GetNodeAttrRealParse(prop, 'width', CanvasWidth, Parser));
2531+
CanvasHeigth := round(GetNodeAttrRealParse(prop, 'heigth', CanvasHeigth, Parser));
2532+
end;
25172533
prop := prop.NextSibling;
25182534
end;
25192535
// Create and position the obstacle
@@ -2527,6 +2543,37 @@ procedure TWorld_ODE.LoadObstaclesFromXML(XMLFile: string; OffsetDef: TSolidDef;
25272543
end;
25282544
if obstacle.NodeName = 'cuboid' then begin
25292545
CreateObstacleBox(NewObstacle, sizeX, sizeY, sizeZ, posX, posY, posZ);
2546+
if HasCanvas then begin
2547+
(NewObstacle.GLObj as TGLCube).Parts := (NewObstacle.GLObj as TGLCube).Parts - [cpfront]; // remove the side where the canvas will be placed
2548+
NewObstacle.CanvasGLObj := TGLSceneObject(NewObstacle.GLObj.AddNewChild(TGLPlane));
2549+
2550+
NewObstacle.PaintBitmap := TBitmap.Create;
2551+
NewObstacle.PaintBitmap.Width := CanvasWidth;
2552+
NewObstacle.PaintBitmap.Height := CanvasHeigth;
2553+
NewObstacle.PaintBitmap.PixelFormat := pf24bit;
2554+
NewObstacle.PaintBitmap.Canvas.Brush.Color := clWhite;
2555+
NewObstacle.PaintBitmap.Canvas.pen.Color := clblack;
2556+
NewObstacle.PaintBitmap.Canvas.FillRect(0, 0, CanvasWidth, CanvasHeigth);
2557+
//NewObstacle.PaintBitmap.Canvas.TextOut(0,0,'Hello World!');
2558+
//newSolid.PaintBitmap.Canvas.Ellipse(0,0,127,127);
2559+
with (NewObstacle.CanvasGLObj as TGLPlane) do begin
2560+
position.Z := sizeZ/2;
2561+
width := sizeX;
2562+
Height := sizeY;
2563+
//Material.Texture.Image.LoadFromFile('gy_logo.jpg');
2564+
Material.Texture.Image.Assign(NewObstacle.PaintBitmap);
2565+
Material.Texture.Disabled := false;
2566+
Material.Texture.TextureMode := tmModulate;
2567+
end;
2568+
2569+
with NewObstacle do begin
2570+
PaintBitmapCorner[0] := sizeX/2;
2571+
PaintBitmapCorner[1] := sizeY/2;
2572+
PaintBitmapCorner[2] := sizeZ/2;
2573+
end;
2574+
HasCanvas := false;
2575+
end;
2576+
25302577
end else if obstacle.NodeName = 'cylinder' then begin
25312578
CreateCylinderObstacle(NewObstacle, max(radius, sizeX), sizeZ, posX, posY, posZ);
25322579
end else if obstacle.NodeName = 'sphere' then begin
@@ -4021,7 +4068,7 @@ constructor TWorld_ODE.create;
40214068
//Create physic
40224069
world := dWorldCreate();
40234070
// dWorldSetQuickStepNumIterations(world, 10);
4024-
Ode_QuickStepIters := 10;
4071+
Ode_QuickStepIters := 20;
40254072
dWorldSetQuickStepNumIterations(world, Ode_QuickStepIters);
40264073
space := dSimpleSpaceCreate(nil);
40274074
//space := dHashSpaceCreate(nil);
@@ -4042,13 +4089,18 @@ constructor TWorld_ODE.create;
40424089
dWorldSetCFM(world, Ode_CFM);
40434090
dWorldSetERP(world, Ode_ERP);
40444091

4045-
//dWorldSetAngularDamping(world, 0.8);
4046-
//dWorldSetLinearDamping(world, 0.8);
4092+
//dWorldSetAngularDamping(world, 0);
4093+
//dWorldSetLinearDamping(world, 0);
4094+
//dWorldSetMaxAngularSpeed(world, Infinity);
40474095

40484096
//if FileExists('ground.jpg') then begin
40494097
// FViewer.GLMaterialLibrary.AddTextureMaterial('Ground', 'ground.jpg');
40504098
//end;
40514099

4100+
//dWorldSetAutoDisableFlag(world, 1);
4101+
//dWorldSetAngularDampingThreshold(world, 0.01);
4102+
//dWorldSetAngularDamping(world, 0.1);
4103+
40524104
LoadSceneFromXML('scene.xml');
40534105

40544106
SetCameraTarget(0);
@@ -4141,6 +4193,8 @@ procedure TFViewer.FormCreate(Sender: TObject);
41414193
Application.UpdateFormatSettings := false;
41424194
DefaultFormatSettings.DecimalSeparator := '.';
41434195

4196+
//Bmp32 := nil;
4197+
41444198
SetCurrentDir(ExtractFilePath(Application.ExeName));
41454199

41464200
if ParamCount > 0 then begin
@@ -4188,8 +4242,9 @@ procedure TFViewer.FormCreate(Sender: TObject);
41884242
end;
41894243

41904244
IniPropStorage.IniFileName := GetIniFineName;
4245+
SetProcessAffinityMask(GetCurrentProcess(), 1);
41914246
// GetProcessAffinityMask(
4192-
// SetThreadAffinityMask(GetCurrentThreadId(), 1);
4247+
SetThreadAffinityMask(GetCurrentThread(), 1);
41934248
// SetThreadAffinityMask(GetCurrentProcessId(), 1);
41944249
QueryPerformanceFrequency(t_delta);
41954250
t_delta := t_delta div 1000;
@@ -4285,6 +4340,7 @@ function TFViewer.GLSceneViewerPick(X, Y: Integer): TGLCustomSceneObject;
42854340
var pick : TGLCustomSceneObject;
42864341
Pos: TdVector3;
42874342
begin
4343+
42884344
pick:=(GLSceneViewer.Buffer.GetPickedObject(x, y) as TGLCustomSceneObject);
42894345

42904346
if Assigned(pick) then begin
@@ -4316,7 +4372,7 @@ procedure AxisTorqueModel(axis: TAxis; Theta, w, dt: double; var T: double);
43164372
ev, ebt: double;
43174373
Td, dtheta, TB, TK, tau: double;
43184374
begin
4319-
max_delta_Im := 0.15; // A/ms
4375+
max_delta_Im := 0.5; // A/ms
43204376
with Axis do begin
43214377
// If active use PID controller
43224378
if Motor.active then begin
@@ -4406,9 +4462,9 @@ procedure AxisTorqueModel(axis: TAxis; Theta, w, dt: double; var T: double);
44064462
Motor.Im := 0;
44074463
end;
44084464

4409-
Motor.PowerDrain := Motor.Im * Motor.voltage * WorldODE.Ode_dt;
4465+
Motor.PowerDrain := Motor.Im * Motor.voltage;
44104466
if Motor.PowerDrain > 0 then begin
4411-
Motor.EnergyDrain := Motor.EnergyDrain + Motor.PowerDrain;
4467+
Motor.EnergyDrain := Motor.EnergyDrain + Motor.PowerDrain * WorldODE.Ode_dt;
44124468
end;
44134469

44144470
// coulomb friction
@@ -4445,7 +4501,7 @@ procedure AxisTorqueModel(axis: TAxis; Theta, w, dt: double; var T: double);
44454501

44464502
TK := (Motor.KGearBox + sqrt(Motor.KGearBox) * abs(dtheta)) * dtheta;
44474503

4448-
Td := TK - TB;
4504+
Td := TK + TB;
44494505

44504506
{if abs(Motor.JRotor / Td) < WorldODE.Ode_dt then begin
44514507
if Td > 0 then Td := 0.5 *Motor.JRotor / WorldODE.Ode_dt
@@ -4462,7 +4518,7 @@ procedure AxisTorqueModel(axis: TAxis; Theta, w, dt: double; var T: double);
44624518
end else begin
44634519
//T := Motor.Im * Motor.Ki * Motor.GearRatio - Friction.Bv * w - Spring.K * diffangle(Theta, Spring.ZeroPos);
44644520
T := Motor.Im * Motor.Ki * Motor.GearRatio - Friction.Bv * w - Spring.K * (Theta - Spring.ZeroPos);
4465-
//T := Motor.Im * Motor.Ki * Motor.GearRatio - Friction.Bv * w - Spring.K * (Theta - Spring.ZeroPos);
4521+
//if (abs(w) < 0.05) and (abs(T) < abs(Friction.Fc)) then T := 0;
44664522
end;
44674523
end;
44684524
end;
@@ -4645,6 +4701,11 @@ procedure TFViewer.UpdateGLScene;
46454701
end;
46464702

46474703
end;
4704+
4705+
for r := 0 to WorldODE.Obstacles.Count-1 do begin
4706+
WorldODE.Obstacles[r].UpdateGLCanvas;
4707+
end;
4708+
46484709
end;
46494710

46504711

@@ -4664,7 +4725,7 @@ procedure TFViewer.GLCadencerProgress(Sender: TObject; const deltaTime, newTime:
46644725
begin
46654726
//GLScene.CurrentGLCamera.Position := GLDummyCamPos.Position;
46664727
GLCamera.Position := GLDummyCamPos.Position;
4667-
if WorldODE.ODEEnable <> False then begin
4728+
if WorldODE.ODEEnable then begin
46684729
QueryPerformanceCounter(t_start);
46694730
t_itot := 0;
46704731

@@ -4794,11 +4855,12 @@ procedure TFViewer.GLCadencerProgress(Sender: TObject; const deltaTime, newTime:
47944855
with WorldODE.Robots[r] do begin
47954856
//if not active then continue; //TODO
47964857
theta := Axes[i].GetPos();
4797-
w := Axes[i].GetSpeed();
4858+
w := Axes[i].GetSpeed(WorldODE.Ode_dt);
47984859
//if not Axes[i].Motor.active then continue; //TODO
47994860

4861+
Axes[i].TotalTorque := 0;
48004862
//AxisTorqueModel(Axes[i], Theta, Axes[i].filt_speed, Tq);
4801-
AxisTorqueModel(Axes[i], Theta, w, WorldODE.Ode_dt ,Tq);
4863+
AxisTorqueModel(Axes[i], Theta, w, WorldODE.Ode_dt, Tq);
48024864
// Apply it to the axis
48034865
Axes[i].AddTorque(Tq);
48044866
// Apply Extra torque
@@ -4904,6 +4966,7 @@ procedure TFViewer.GLCadencerProgress(Sender: TObject; const deltaTime, newTime:
49044966
t_itot := t_itot + t_i2 - t_i1;
49054967

49064968
// Post Process Sensors
4969+
49074970
for i := 0 to WorldODE.Sensors.Count - 1 do begin
49084971
with WorldODE.Sensors[i] do begin
49094972
PostProcess;
@@ -5158,6 +5221,7 @@ procedure TFViewer.FormShow(Sender: TObject);
51585221
FParams.BSetTrailParsClick(Sender);
51595222

51605223
FParams.ShowParsedScene;
5224+
FParams.BSetFPSClick(Sender);
51615225

51625226
MakeFullyVisible();
51635227
UpdateGLScene;

tx15.bmp

191 KB
Binary file not shown.

0 commit comments

Comments
 (0)