@@ -85,30 +85,39 @@ const VideoFeed = (props) => {
8585 * re-connecting upon re-renders.
8686 */
8787 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 )
9090
9191 /**
9292 * Subscribe to the image topic.
9393 */
9494 const cameraCallback = useCallback (
9595 ( 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
10697 } ,
107- [ latestImageTimestamp , setLatestRenderedImg , props . updateRateHz ]
98+ [ latestImageMessage ]
10899 )
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 ( ) )
109115 useEffect ( ( ) => {
110116 console . log ( 'subscribing to img topic' )
111117 let topic = subscribeToROSTopic ( ros . current , props . topic , 'sensor_msgs/CompressedImage' , cameraCallback )
118+ setTimeout ( ( ) => {
119+ setResubscribeRateCurrentDate ( new Date ( ) )
120+ } , 1000 / props . resubscribeRateHz )
112121 const cleanup = ( ) => {
113122 console . log ( 'unsubscribing from img topic' )
114123 unsubscribeFromROSTopic ( topic , cameraCallback )
@@ -123,7 +132,7 @@ const VideoFeed = (props) => {
123132 window . removeEventListener ( 'beforeunload' , cleanup )
124133 cleanup ( )
125134 }
126- } , [ cameraCallback , props . topic ] )
135+ } , [ cameraCallback , props . topic , props . resubscribeRateHz , resubscribeRateCurrentDate , setResubscribeRateCurrentDate ] )
127136
128137 // Callback to resize the image based on the parent width and height
129138 const resizeImage = useCallback ( ( ) => {
@@ -192,18 +201,20 @@ const VideoFeed = (props) => {
192201
193202 // Render the component
194203 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+ </ >
207218 )
208219}
209220VideoFeed . propTypes = {
@@ -218,6 +229,8 @@ VideoFeed.propTypes = {
218229 topic : PropTypes . string . isRequired ,
219230 // The rate at which to update the video feed, in Hz
220231 updateRateHz : PropTypes . number . isRequired ,
232+ // The rate at which to resubscribe to the image topic
233+ resubscribeRateHz : PropTypes . number . isRequired ,
221234 /**
222235 * An optional callback function for when the user clicks on the video feed.
223236 * This function should take in two parameters, `x` and `y`, which are the
@@ -228,7 +241,8 @@ VideoFeed.propTypes = {
228241}
229242VideoFeed . defaultProps = {
230243 topic : CAMERA_FEED_TOPIC ,
231- updateRateHz : 10
244+ updateRateHz : 3 ,
245+ resubscribeRateHz : 0.1
232246}
233247
234248export default VideoFeed
0 commit comments