@@ -376,7 +376,7 @@ Linear 2D translational spring damper model
376
376
@variables begin
377
377
v_relx (t)
378
378
v_rely (t)
379
- ω_rel (t) = 0
379
+ w_rel (t) = 0
380
380
s_relx (t)
381
381
s_rely (t)
382
382
phi_rel (t) = 0
@@ -397,9 +397,9 @@ Linear 2D translational spring damper model
397
397
phi_rel ~ frame_b. phi - frame_a. phi
398
398
v_relx ~ D (s_relx)
399
399
v_rely ~ D (s_rely)
400
- ω_rel ~ D (phi_rel)
400
+ w_rel ~ D (phi_rel)
401
401
402
- tau ~ c_phi * (phi_rel - phi_rel0) + d_phi * ω_rel
402
+ tau ~ c_phi * (phi_rel - phi_rel0) + d_phi * w_rel
403
403
frame_a. tau ~ - tau
404
404
frame_b. tau ~ tau
405
405
f_x ~ c_x * (s_relx - s_relx0) + d_x * v_relx
@@ -412,3 +412,189 @@ Linear 2D translational spring damper model
412
412
# lossPower ~ d_x * v_relx * v_relx + d_y * v_rely * v_rely
413
413
end
414
414
end
415
+
416
+
417
+ @mtkmodel SimpleWheel begin
418
+ @structural_parameters begin
419
+ friction_model = :viscous
420
+ end
421
+ @parameters begin
422
+ (radius = 0.3 ), [description = " Radius of the wheel" ]
423
+ (color[1 : 4 ] = [1 , 0 , 0 , 1 ]), [description = " Color of the wheel in animations" ]
424
+ μ = 1e9 , [description = " Viscous friction coefficient" ]
425
+ # Fy0 = 1e4, [description = "Lateral friction force at zero longitudinal force"]
426
+ # μx = Fy0, [description = "Maximum longitudinal friction force"]
427
+ end
428
+ @variables begin
429
+ θ (t), [guess= 0 , description= " wheel angle" ] # wheel angle
430
+ Vx (t), [guess= 0 , description= " longitudinal velocity (resolved in local frame)" ]
431
+ Vy (t)= 0 , [description= " lateral velocity (resolved in local frame)" ]
432
+ Fy (t), [guess= 0 , description= " lateral friction force" ]
433
+ Fx (t), [guess= 0 , description= " applied longitudinal wheel force" ]
434
+ end
435
+ @components begin
436
+ frame_a = Frame ()
437
+ thrust = Blocks. RealInput ()
438
+ end
439
+ begin
440
+ R_W_F = ori_2d (frame_a) # rotation matrix, local to global
441
+ veqs = R_W_F' * [D (frame_a. x), D (frame_a. y)] # ~ [Vx, Vy]
442
+ feqs = R_W_F' * [frame_a. fx, frame_a. fy] # ~ [Fx, Fy]
443
+ end
444
+
445
+
446
+ @equations begin
447
+ θ ~ frame_a. phi
448
+
449
+ # road friction
450
+ Fx ~ thrust. u
451
+ # if friction_model == :viscous
452
+ Fy ~ μ* Vy
453
+ # elseif friction_model == :ellipse
454
+ # Fy ~ Fy0*sqrt(1 - (Fx/μ)^2)*Vy
455
+ # end
456
+ veqs[1 ] ~ Vx
457
+ veqs[2 ] ~ Vy
458
+ feqs[1 ] ~ Fx
459
+ feqs[2 ] ~ Fy
460
+
461
+ # R'*[D(frame.x), D(frame.y)] ~ [Vx, Vy]
462
+ # R'*[frame.fx, frame.fy] ~ [Fx, Fy]
463
+
464
+ frame_a. tau ~ 0 # Assume that wheel does not transmit any torque
465
+ end
466
+ end
467
+
468
+ """
469
+ limit_S_triple(x_max, x_sat, y_max, y_sat, x)
470
+
471
+ Returns a point-symmetric Triple S-Function
472
+
473
+ A point symmetric interpolation between points `(0, 0), (x_max, y_max) and (x_sat, y_sat)`, provided `x_max < x_sat`. The approximation is done in such a way that the 1st function's derivative is zero at points `(x_max, y_max)` and `(x_sat, y_sat)`. Thus, the 1st function's derivative is continuous for all `x`. The higher derivatives are discontinuous at these points.
474
+ """
475
+ function limit_S_triple (x_max, x_sat, y_max, y_sat, x)
476
+ if x > x_max
477
+ return limit_S_form (x_max, x_sat, y_max, y_sat, x)
478
+ elseif x < - x_max
479
+ return limit_S_form (- x_max, - x_sat, - y_max, - y_sat, x)
480
+ else
481
+ return limit_S_form (- x_max, x_max, - y_max, y_max, x)
482
+ end
483
+ end
484
+
485
+
486
+ """
487
+ limit_S_form(x_min, x_max, y_min, y_max, x)
488
+
489
+ Returns a S-shaped transition
490
+
491
+ A smooth transition between points `(x_min, y_min)` and `(x_max, y_max)`. The transition is done in such a way that the 1st function's derivative is continuous for all `x`. The higher derivatives are discontinuous at input points.
492
+ """
493
+ function limit_S_form (x_min, x_max, y_min, y_max, x)
494
+ x2 = x - x_max/ 2 - x_min/ 2
495
+ x2 = x2* 2 / (x_max- x_min)
496
+ y = clamp (- 0.5 * x2^ 3 + 1.5 * x2, - 1 , 1 )
497
+ y = y* (y_max- y_min)/ 2
498
+ y = y + y_max/ 2 + y_min/ 2
499
+ return y
500
+ end
501
+
502
+
503
+ @register_symbolic limit_S_triple (x_max:: Real , x_sat:: Real , y_max:: Real , y_sat:: Real , x:: Real )
504
+ @register_symbolic limit_S_form (x_min:: Real , x_max:: Real , y_min:: Real , y_max:: Real , x:: Real )
505
+
506
+
507
+ @component function SlipBasedWheelJoint (;
508
+ name,
509
+ r = [1 , 0 ],
510
+ N,
511
+ vAdhesion_min,
512
+ vSlide_min,
513
+ sAdhesion,
514
+ sSlide,
515
+ mu_A,
516
+ mu_S,
517
+ render = true ,
518
+ color = [0.1 , 0.1 , 0.1 , 1 ],
519
+ z = 0 ,
520
+ diameter = 0.1 ,
521
+ width = diameter * 0.6 ,
522
+ radius = 0.1 ,
523
+ w_roll = nothing ,
524
+ )
525
+ systems = @named begin
526
+ frame_a = Frame ()
527
+ flange_a = Rotational. Flange ()
528
+ dynamicLoad = Blocks. RealInput ()
529
+ end
530
+ pars = @parameters begin
531
+ r[1 : 2 ] = r, [description = " Driving direction of the wheel at angle phi = 0" ]
532
+ N = N, [description = " Base normal load" ]
533
+ vAdhesion_min = vAdhesion_min, [description = " Minimum adhesion velocity" ]
534
+ vSlide_min = vSlide_min, [description = " Minimum sliding velocity" ]
535
+ sAdhesion = sAdhesion, [description = " Adhesion slippage" ]
536
+ sSlide = sSlide, [description = " Sliding slippage" ]
537
+ mu_A = mu_A, [description = " Friction coefficient at adhesion" ]
538
+ mu_S = mu_S, [description = " Friction coefficient at sliding" ]
539
+ render = render, [description = " Render the wheel in animations" ]
540
+ color[1 : 4 ] = color, [description = " Color of the wheel in animations" ]
541
+ z = 0 , [description = " Position z of the body" ]
542
+ diameter = diameter, [description = " Diameter of the rims" ]
543
+ width = width, [description = " Width of the wheel" ]
544
+ radius = radius, [description = " Radius of the wheel" ]
545
+ end
546
+ r = collect (r)
547
+ l = Multibody. _norm (r)
548
+ e = Multibody. _normalize (r) # Unit vector in direction of r
549
+
550
+ vars = @variables begin
551
+ e0 (t)[1 : 2 ], [description= " Unit vector in direction of r resolved w.r.t. inertial frame" ]
552
+ phi_roll (t), [guess= 0 , description= " wheel angle" ] # wheel angle
553
+ (w_roll (t)= w_roll), [guess= 0 , description= " Roll velocity of wheel" ]
554
+ v (t)[1 : 2 ], [description= " velocity" ]
555
+ v_lat (t), [guess= 0 , description= " Driving in lateral direction" ]
556
+ v_long (t), [guess= 0 , description= " Velocity in longitudinal direction" ]
557
+ v_slip_long (t), [guess= 0 , description= " Slip velocity in longitudinal direction" ]
558
+ v_slip_lat (t), [guess= 0 , description= " Slip velocity in lateral direction" ]
559
+ v_slip (t), [description= " Slip velocity" ]
560
+ f (t), [description= " Longitudinal force" ]
561
+ f_lat (t), [description= " Longitudinal force" ]
562
+ f_long (t), [description= " Longitudinal force" ]
563
+ fN (t), [description= " Base normal load" ]
564
+ vAdhesion (t), [description= " Adhesion velocity" ]
565
+ vSlide (t), [description= " Sliding velocity" ]
566
+ end
567
+ e0 = collect (e0)
568
+ v = collect (v)
569
+ vars = [
570
+ e0; phi_roll; w_roll; v; v_lat; v_long; v_slip_long; v_slip_lat; v_slip; f; f_lat; f_long; fN; vAdhesion; vSlide
571
+ ]
572
+
573
+ R = ori_2d (frame_a)
574
+
575
+ equations = [
576
+ e0 .~ R * e
577
+ v .~ D .([frame_a. x, frame_a. y])
578
+
579
+ phi_roll ~ flange_a. phi
580
+ w_roll ~ D (phi_roll)
581
+ v_long ~ v' * e0
582
+ v_lat ~ - v[1 ] * e0[2 ] + v[2 ] * e0[1 ]
583
+ v_slip_lat ~ v_lat - 0
584
+ v_slip_long ~ v_long - radius * w_roll
585
+ v_slip ~ sqrt (v_slip_long^ 2 + v_slip_lat^ 2 ) + 0.0001
586
+ - f_long * radius ~ flange_a. tau
587
+ frame_a. tau ~ 0
588
+ vAdhesion ~ max (vAdhesion_min, sAdhesion * abs (radius * w_roll))
589
+ vSlide ~ max (vSlide_min, sSlide * abs (radius * w_roll))
590
+ fN ~ max (0 , N + dynamicLoad. u)
591
+ f ~ fN * limit_S_triple (vAdhesion, vSlide, mu_A, mu_S, v_slip)
592
+ f_long ~ f * v_slip_long / v_slip
593
+ f_lat ~ f * v_slip_lat / v_slip
594
+ f_long ~ [frame_a. fx, frame_a. fy]' e0
595
+ f_lat ~ [frame_a. fy, - frame_a. fx]' e0
596
+ ]
597
+
598
+ return ODESystem (equations, t, vars, pars; name, systems)
599
+
600
+ end
0 commit comments