1
1
package us .ihmc .perception ;
2
2
3
- import com . google . common . util . concurrent . ThreadFactoryBuilder ;
3
+ import org . bytedeco . opencv . opencv_core . GpuMat ;
4
4
import us .ihmc .avatar .drcRobot .ROS2SyncedRobotModel ;
5
- import us .ihmc .euclid .referenceFrame .ReferenceFrame ;
6
5
import us .ihmc .humanoidRobotics .communication .ControllerFootstepQueueMonitor ;
6
+ import us .ihmc .commons .thread .RepeatingTaskThread ;
7
+ import us .ihmc .euclid .referenceFrame .ReferenceFrame ;
7
8
import us .ihmc .log .LogTools ;
9
+ import us .ihmc .perception .camera .CameraIntrinsics ;
10
+ import us .ihmc .perception .filters .DepthImageBodyCollisionFilter ;
8
11
import us .ihmc .perception .gpuHeightMap .RapidHeightMapManager ;
9
- import us .ihmc .perception .heightMap .TerrainMapData ;
10
12
import us .ihmc .robotics .physics .RobotCollisionModel ;
11
13
import us .ihmc .robotics .robotSide .RobotSide ;
12
14
import us .ihmc .ros2 .ROS2Node ;
13
15
import us .ihmc .sensorProcessing .heightMap .HeightMapData ;
14
16
import us .ihmc .sensorProcessing .heightMap .HeightMapParameters ;
15
17
import us .ihmc .sensors .ImageSensor ;
16
18
17
- import java .util .concurrent .Executors ;
18
- import java .util .concurrent .ScheduledExecutorService ;
19
- import java .util .concurrent .ThreadFactory ;
20
- import java .util .concurrent .TimeUnit ;
19
+ import java .time .Instant ;
21
20
22
- public class RapidHeightMapThread
21
+ public class RapidHeightMapThread extends RepeatingTaskThread
23
22
{
23
+ private final DepthImageBodyCollisionFilter bodyCollisionFilter ;
24
24
private final RapidHeightMapManager heightMapManager ;
25
25
private final Object heightMapLock = new Object ();
26
26
27
27
private final ImageSensor imageSensor ;
28
- private final ReferenceFrame sensorFrame ;
28
+ private final ReferenceFrame cameraFrame ;
29
29
private final ReferenceFrame zUpSensorFrame ;
30
30
private final int depthImageKey ;
31
- private ScheduledExecutorService scheduler ;
32
31
33
32
public RapidHeightMapThread (ROS2Node ros2Node ,
34
33
ROS2SyncedRobotModel syncedRobotModel ,
@@ -38,17 +37,19 @@ public RapidHeightMapThread(ROS2Node ros2Node,
38
37
ControllerFootstepQueueMonitor controllerFootstepQueueMonitor ,
39
38
HeightMapParameters heightMapParameters )
40
39
{
40
+ super (imageSensor .getSensorName () + RapidHeightMapThread .class .getSimpleName ());
41
+
41
42
this .imageSensor = imageSensor ;
42
43
this .depthImageKey = depthImageKey ;
43
44
44
- sensorFrame = syncedRobotModel .getReferenceFrames ().getSteppingCameraFrame ();
45
+ cameraFrame = syncedRobotModel .getReferenceFrames ().getSteppingCameraFrame ();
45
46
zUpSensorFrame = syncedRobotModel .getReferenceFrames ().getSteppingCameraZUpFrame ();
46
47
47
48
ReferenceFrame leftFootFrame = syncedRobotModel .getReferenceFrames ().getSoleFrame (RobotSide .LEFT );
48
49
ReferenceFrame rightFootFrame = syncedRobotModel .getReferenceFrames ().getSoleFrame (RobotSide .LEFT );
49
50
51
+ bodyCollisionFilter = new DepthImageBodyCollisionFilter (robotCollisionModel , syncedRobotModel .getFullRobotModel ().getRootBody ());
50
52
heightMapManager = new RapidHeightMapManager (ros2Node ,
51
- robotCollisionModel ,
52
53
syncedRobotModel .getFullRobotModel (),
53
54
syncedRobotModel .getRobotModel ().getSimpleRobotName (),
54
55
leftFootFrame ,
@@ -57,29 +58,35 @@ public RapidHeightMapThread(ROS2Node ros2Node,
57
58
heightMapParameters );
58
59
}
59
60
60
- public void start ()
61
- {
62
- // We create a ThreadFactory here so that when profiling the thread, there is a user-friendly name to identify it with
63
- ThreadFactory threadFactory = new ThreadFactoryBuilder ().setNameFormat ("RemoteHeightMapUpdateThread" ).build ();
64
- scheduler = Executors .newScheduledThreadPool (1 , threadFactory );
65
- scheduler .scheduleWithFixedDelay (this ::update , 100 , 10 , TimeUnit .MILLISECONDS );
66
- }
67
-
68
- public void update ()
61
+ @ Override
62
+ protected void runTask ()
69
63
{
70
64
try
71
65
{
72
66
imageSensor .waitForGrab ();
73
67
RawImage depthImage = imageSensor .getImage (depthImageKey );
74
68
69
+ // Get everything we need from the image
70
+ GpuMat latestDepthImage = depthImage .getGpuImageMat ();
71
+ Instant acquisitionTime = depthImage .getAcquisitionTime ();
72
+ CameraIntrinsics depthIntrinsicsCopy = depthImage .getIntrinsicsCopy ();
73
+
74
+ // Process body collisions
75
+ GpuMat depthImageWithoutBodyCollisions = new GpuMat (latestDepthImage .size (), latestDepthImage .type ());
76
+ bodyCollisionFilter .process (latestDepthImage , depthImageWithoutBodyCollisions , depthIntrinsicsCopy , cameraFrame );
77
+
75
78
// Update height map
76
79
synchronized (heightMapLock )
77
80
{
78
- heightMapManager .updateAndPublishHeightMap (depthImage , sensorFrame , zUpSensorFrame );
81
+ heightMapManager .updateAndPublishHeightMap (depthImageWithoutBodyCollisions , acquisitionTime , depthIntrinsicsCopy , cameraFrame , zUpSensorFrame );
79
82
}
80
83
84
+ depthImageWithoutBodyCollisions .close ();
81
85
depthImage .release ();
82
86
}
87
+ catch (InterruptedException ignored )
88
+ {
89
+ }
83
90
catch (Exception e )
84
91
{
85
92
LogTools .error (e );
@@ -94,9 +101,12 @@ public HeightMapData getLatestHeightMapData()
94
101
}
95
102
}
96
103
97
- public void destroy ()
104
+ @ Override
105
+ public void kill ()
98
106
{
99
- scheduler .shutdown ();
107
+ super .kill ();
108
+ interrupt ();
109
+
100
110
heightMapManager .destroy ();
101
111
}
102
112
}
0 commit comments