@@ -85,30 +85,39 @@ const VideoFeed = (props) => {
85
85
* re-connecting upon re-renders.
86
86
*/
87
87
const ros = useRef ( useROS ( ) . ros )
88
- // Store the latest image timestamp in a ref to avoid re-generating cameraCallback
89
- const latestImageTimestamp = useRef ( null )
88
+ // Store the latest image message in a ref to avoid re-generating cameraCallback
89
+ const latestImageMessage = useRef ( null )
90
90
91
91
/**
92
92
* Subscribe to the image topic.
93
93
*/
94
94
const cameraCallback = useCallback (
95
95
( message ) => {
96
- // console.log('Got camera message', message)
97
- if ( ! latestImageTimestamp . current || props . updateRateHz <= 0 ) {
98
- setLatestRenderedImg ( message )
99
- } else {
100
- let currTime = message . header . stamp . sec + message . header . stamp . nanosec * 1e-9
101
- if ( currTime - latestImageTimestamp . current >= 1.0 / props . updateRateHz ) {
102
- setLatestRenderedImg ( message )
103
- latestImageTimestamp . current = currTime
104
- }
105
- }
96
+ latestImageMessage . current = message
106
97
} ,
107
- [ latestImageTimestamp , setLatestRenderedImg , props . updateRateHz ]
98
+ [ latestImageMessage ]
108
99
)
100
+
101
+ /**
102
+ * Create a timer to re-render the latest image every props.updateRateHz
103
+ */
104
+ const [ updateHzCurrentDate , setUpdateHzCurrentDate ] = useState ( new Date ( ) )
105
+ useEffect ( ( ) => {
106
+ setTimeout ( ( ) => {
107
+ setUpdateHzCurrentDate ( new Date ( ) )
108
+ setLatestRenderedImg ( latestImageMessage . current )
109
+ } , 1000 / props . updateRateHz )
110
+ } , [ updateHzCurrentDate , setUpdateHzCurrentDate , props . updateRateHz , setLatestRenderedImg , latestImageMessage ] )
111
+ /**
112
+ * Create a timer to re-render the latest image every props.updateRateHz
113
+ */
114
+ const [ resubscribeRateCurrentDate , setResubscribeRateCurrentDate ] = useState ( new Date ( ) )
109
115
useEffect ( ( ) => {
110
116
console . log ( 'subscribing to img topic' )
111
117
let topic = subscribeToROSTopic ( ros . current , props . topic , 'sensor_msgs/CompressedImage' , cameraCallback )
118
+ setTimeout ( ( ) => {
119
+ setResubscribeRateCurrentDate ( new Date ( ) )
120
+ } , 1000 / props . resubscribeRateHz )
112
121
const cleanup = ( ) => {
113
122
console . log ( 'unsubscribing from img topic' )
114
123
unsubscribeFromROSTopic ( topic , cameraCallback )
@@ -123,7 +132,7 @@ const VideoFeed = (props) => {
123
132
window . removeEventListener ( 'beforeunload' , cleanup )
124
133
cleanup ( )
125
134
}
126
- } , [ cameraCallback , props . topic ] )
135
+ } , [ cameraCallback , props . topic , props . resubscribeRateHz , resubscribeRateCurrentDate , setResubscribeRateCurrentDate ] )
127
136
128
137
// Callback to resize the image based on the parent width and height
129
138
const resizeImage = useCallback ( ( ) => {
@@ -192,18 +201,20 @@ const VideoFeed = (props) => {
192
201
193
202
// Render the component
194
203
return (
195
- < img
196
- src = { `data:image/jpeg;base64,${ latestRenderedImg ? latestRenderedImg . data : '' } ` }
197
- alt = 'Live video feed from the robot'
198
- style = { {
199
- width : imgWidth ,
200
- height : imgHeight ,
201
- display : 'block' ,
202
- alignItems : 'center' ,
203
- justifyContent : 'center'
204
- } }
205
- onClick = { props . pointClicked ? imageClicked : null }
206
- />
204
+ < >
205
+ < img
206
+ src = { `data:image/jpeg;base64,${ latestRenderedImg ? latestRenderedImg . data : '' } ` }
207
+ alt = 'Live video feed from the robot'
208
+ style = { {
209
+ width : imgWidth ,
210
+ height : imgHeight ,
211
+ display : 'block' ,
212
+ alignItems : 'center' ,
213
+ justifyContent : 'center'
214
+ } }
215
+ onClick = { props . pointClicked ? imageClicked : null }
216
+ />
217
+ </ >
207
218
)
208
219
}
209
220
VideoFeed . propTypes = {
@@ -218,6 +229,8 @@ VideoFeed.propTypes = {
218
229
topic : PropTypes . string . isRequired ,
219
230
// The rate at which to update the video feed, in Hz
220
231
updateRateHz : PropTypes . number . isRequired ,
232
+ // The rate at which to resubscribe to the image topic
233
+ resubscribeRateHz : PropTypes . number . isRequired ,
221
234
/**
222
235
* An optional callback function for when the user clicks on the video feed.
223
236
* This function should take in two parameters, `x` and `y`, which are the
@@ -228,7 +241,8 @@ VideoFeed.propTypes = {
228
241
}
229
242
VideoFeed . defaultProps = {
230
243
topic : CAMERA_FEED_TOPIC ,
231
- updateRateHz : 10
244
+ updateRateHz : 3 ,
245
+ resubscribeRateHz : 0.1
232
246
}
233
247
234
248
export default VideoFeed
0 commit comments