31
31
32
32
public class RDXMultiContactRegionGraphic implements RenderableProvider
33
33
{
34
- private static final Color POLYGON_GRAPHIC_COLOR = Color .valueOf ("DEE933" );
34
+ private static final Color NOMINAL_POLYGON_GRAPHIC_COLOR = Color .valueOf ("DEE933" );
35
+ private static final Color LOW_STABILITY_POLYGON_GRAPHIC_COLOR = Color .valueOf ("EB3D40" );
35
36
private static final double STABILITY_GRAPHIC_HEIGHT = 2.0 ;
36
37
37
- private final ConvexPolygon2D multiContactSupportRegion = new ConvexPolygon2D ();
38
+ private final ConvexPolygon2D supportRegion = new ConvexPolygon2D ();
38
39
39
40
private final FramePoint3D comCurrent = new FramePoint3D ();
41
+ private final FramePoint3D comDesired = new FramePoint3D ();
40
42
private final FramePoint3D comXYAtFootHeight = new FramePoint3D ();
41
- private final ConvexPolygon2D closestProximityEdge = new ConvexPolygon2D ();
43
+ private final FramePoint3D desiredCoMXYAtFootHeight = new FramePoint3D ();
42
44
43
45
private int minimumEdgeIndex ;
44
46
private double minimumEdgeDistance ;
45
47
46
48
private final ModelBuilder modelBuilder = new ModelBuilder ();
47
49
private final RDXMultiColorMeshBuilder meshBuilder = new RDXMultiColorMeshBuilder ();
48
- private final FullHumanoidRobotModel ghostFullRobotModel ;
49
50
private final CenterOfMassReferenceFrame centerOfMassFrame ;
50
51
private final MidFrameZUpFrame midFeetZUpFrame ;
51
52
private final RigidBodyTransform transform = new RigidBodyTransform ();
@@ -55,68 +56,97 @@ public class RDXMultiContactRegionGraphic implements RenderableProvider
55
56
56
57
public RDXMultiContactRegionGraphic (FullHumanoidRobotModel ghostFullRobotModel )
57
58
{
58
- this .ghostFullRobotModel = ghostFullRobotModel ;
59
59
this .centerOfMassFrame = new CenterOfMassReferenceFrame ("ghostCoMFrame" , ReferenceFrame .getWorldFrame (), ghostFullRobotModel .getRootBody ());
60
60
this .midFeetZUpFrame = new MidFrameZUpFrame ("midFeedZUpWhost" ,
61
61
ReferenceFrame .getWorldFrame (),
62
62
ghostFullRobotModel .getSoleFrame (RobotSide .LEFT ),
63
63
ghostFullRobotModel .getSoleFrame (RobotSide .RIGHT ));
64
64
}
65
65
66
- public void update (KinematicsToolboxOutputStatus kinematicsToolboxOutputStatus )
66
+ public void update (KinematicsToolboxOutputStatus kinematicsToolboxOutputStatus , FramePoint3D desiredCoMPosition )
67
67
{
68
- multiContactSupportRegion .clear ();
69
- Object <Point3D > supportRegion = kinematicsToolboxOutputStatus .getSupportRegion ();
70
-
71
- for (int i = 0 ; i < supportRegion .size (); i ++)
72
- {
73
- multiContactSupportRegion .addVertex (supportRegion .get (i ));
74
- }
75
-
76
- multiContactSupportRegion .update ();
77
-
78
- if (multiContactSupportRegion .getNumberOfVertices () < 3 )
79
- {
80
- modelInstance = null ;
81
- lastModel = null ;
82
- return ;
83
- }
84
-
85
68
meshBuilder .clear ();
86
69
70
+ // Update frames and compute mid-feet height
87
71
centerOfMassFrame .update ();
88
72
midFeetZUpFrame .update ();
89
- updateMinimumEdge ();
90
73
91
74
FramePoint3D midFoot = new FramePoint3D (midFeetZUpFrame );
92
75
midFoot .changeFrame (ReferenceFrame .getWorldFrame ());
93
76
double footZ = midFoot .getZ ();
94
77
95
- transform .setTranslationAndIdentityRotation (0.0 , 0.0 , footZ );
96
-
97
- for (int i = 0 ; i < multiContactSupportRegion .getNumberOfVertices (); i ++)
78
+ // Update desired and achieved CoM graphic
98
79
{
99
- Point2DReadOnly v0 = multiContactSupportRegion .getVertex (i );
100
- Point2DReadOnly v1 = multiContactSupportRegion .getNextVertex (i );
80
+ comCurrent .setToZero (centerOfMassFrame );
81
+ comCurrent .changeFrame (ReferenceFrame .getWorldFrame ());
82
+
83
+ meshBuilder .addSphere (0.03f , comCurrent , Color .BLACK );
84
+
85
+ comXYAtFootHeight .setIncludingFrame (comCurrent );
86
+ comXYAtFootHeight .setZ (footZ );
87
+ meshBuilder .addSphere (0.03f , comXYAtFootHeight , Color .BLACK );
88
+
89
+ FramePoint3D comXYElevated = new FramePoint3D (comXYAtFootHeight );
90
+ comXYElevated .addZ (STABILITY_GRAPHIC_HEIGHT );
91
+ meshBuilder .addLine (comXYAtFootHeight , comXYElevated , 0.005f , Color .BLACK );
92
+
93
+ if (desiredCoMPosition != null )
94
+ {
95
+ comDesired .setMatchingFrame (desiredCoMPosition );
96
+ meshBuilder .addSphere (0.03f , comDesired , Color .GREEN );
97
+
98
+ desiredCoMXYAtFootHeight .setIncludingFrame (comDesired );
99
+ desiredCoMXYAtFootHeight .setZ (footZ );
100
+ meshBuilder .addSphere (0.03f , desiredCoMXYAtFootHeight , Color .GREEN );
101
101
102
- Color color = i == minimumEdgeIndex ? Color .RED : POLYGON_GRAPHIC_COLOR ;
103
- meshBuilder .addLine (v0 .getX (), v0 .getY (), footZ , v1 .getX (), v1 .getY (), footZ , 0.01f , color );
102
+ FramePoint3D desiredComXYElevated = new FramePoint3D (desiredCoMXYAtFootHeight );
103
+ desiredComXYElevated .addZ (STABILITY_GRAPHIC_HEIGHT );
104
+ meshBuilder .addLine (desiredCoMXYAtFootHeight , desiredComXYElevated , 0.005f , Color .GREEN );
105
+ }
104
106
}
105
107
106
- meshBuilder .addPolygon (transform , multiContactSupportRegion , POLYGON_GRAPHIC_COLOR );
108
+ // Update region graphic
109
+ Object <Point3D > ikSupportRegion = kinematicsToolboxOutputStatus .getSupportRegion ();
110
+ if (ikSupportRegion .size () >= 3 )
111
+ {
112
+ this .supportRegion .clear ();
113
+
114
+ for (int i = 0 ; i < ikSupportRegion .size (); i ++)
115
+ {
116
+ this .supportRegion .addVertex (ikSupportRegion .get (i ));
117
+ }
118
+
119
+ this .supportRegion .update ();
107
120
108
- comCurrent .setToZero (centerOfMassFrame );
109
- comCurrent .changeFrame (ReferenceFrame .getWorldFrame ());
121
+ if (this .supportRegion .getNumberOfVertices () < 3 )
122
+ {
123
+ modelInstance = null ;
124
+ lastModel = null ;
125
+ return ;
126
+ }
110
127
111
- meshBuilder . addSphere ( 0.03f , comCurrent , Color . BLACK );
128
+ updateMinimumEdge ( );
112
129
113
- comXYAtFootHeight .setIncludingFrame (comCurrent );
114
- comXYAtFootHeight .setZ (footZ );
115
- meshBuilder .addSphere (0.03f , comXYAtFootHeight , Color .BLACK );
130
+ transform .setTranslationAndIdentityRotation (0.0 , 0.0 , footZ );
116
131
117
- FramePoint3D comXYElevated = new FramePoint3D (comXYAtFootHeight );
118
- comXYElevated .addZ (STABILITY_GRAPHIC_HEIGHT );
119
- meshBuilder .addLine (comXYAtFootHeight , comXYElevated , 0.005f , Color .BLACK );
132
+ for (int i = 0 ; i < this .supportRegion .getNumberOfVertices (); i ++)
133
+ {
134
+ Point2DReadOnly v0 = this .supportRegion .getVertex (i );
135
+ Point2DReadOnly v1 = this .supportRegion .getNextVertex (i );
136
+
137
+ Color color = i == minimumEdgeIndex ? Color .RED : NOMINAL_POLYGON_GRAPHIC_COLOR ;
138
+ meshBuilder .addLine (v0 .getX (), v0 .getY (), footZ , v1 .getX (), v1 .getY (), footZ , 0.01f , color );
139
+ }
140
+
141
+ double postureSensitivityThreshold = 0.045 ;
142
+ double stabilityMarginThreshold = 0.12 ;
143
+
144
+ boolean isPostureHighlySensitive = kinematicsToolboxOutputStatus .getSupportRegionSensitivity () > postureSensitivityThreshold ;
145
+ boolean hasLowStabilityMargin = minimumEdgeDistance < stabilityMarginThreshold ;
146
+
147
+ Color polygonGraphicColor = (isPostureHighlySensitive && hasLowStabilityMargin ) ? LOW_STABILITY_POLYGON_GRAPHIC_COLOR : NOMINAL_POLYGON_GRAPHIC_COLOR ;
148
+ meshBuilder .addPolygon (transform , this .supportRegion , polygonGraphicColor );
149
+ }
120
150
121
151
modelBuilder .begin ();
122
152
Mesh mesh = meshBuilder .generateMesh ();
@@ -139,10 +169,10 @@ private void updateMinimumEdge()
139
169
{
140
170
minimumEdgeDistance = Double .POSITIVE_INFINITY ;
141
171
142
- for (int i = 0 ; i < multiContactSupportRegion .getNumberOfVertices (); i ++)
172
+ for (int i = 0 ; i < supportRegion .getNumberOfVertices (); i ++)
143
173
{
144
- Point2DReadOnly v0 = multiContactSupportRegion .getVertex (i );
145
- Point2DReadOnly v1 = multiContactSupportRegion .getNextVertex (i );
174
+ Point2DReadOnly v0 = supportRegion .getVertex (i );
175
+ Point2DReadOnly v1 = supportRegion .getNextVertex (i );
146
176
147
177
double margin = EuclidGeometryTools .distanceFromPoint2DToLine2D (comXYAtFootHeight .getX (), comXYAtFootHeight .getY (), v0 , v1 );
148
178
if (margin < minimumEdgeDistance )
@@ -156,7 +186,7 @@ private void updateMinimumEdge()
156
186
@ Override
157
187
public void getRenderables (Array <Renderable > renderables , Pool <Renderable > pool )
158
188
{
159
- if (multiContactSupportRegion .isEmpty ())
189
+ if (supportRegion .isEmpty ())
160
190
{
161
191
return ;
162
192
}
0 commit comments