@@ -442,17 +442,7 @@ static void mdlUpdate(SimStruct *S, int_T tid)
442442
443443 auto &miTemp = sd.mi [miIndex];
444444
445- if (miTemp->offscreenCam .size () != 0 )
446- {
447- if ( (miTemp->get_d ()->time - miTemp->lastRenderTime ) > miTemp->cameraRenderInterval )
448- {
449- // maintain camera and physics in sync at required camera sample time
450- miTemp->cameraSync .acquire (); // blocking till offscreen buffer is rendered
451- miTemp->lastRenderTime = miTemp->get_d ()->time ;
452- }
453- }
454-
455- // set control inputs
445+ // Step the simulation by one discrete time step. Outputs (sensors and camera) get reflected in the next step
456446 miTemp->step (uVec);
457447}
458448
@@ -525,15 +515,13 @@ void renderingThreadFcn()
525515 while (1 )
526516 {
527517 // Visualization window(s)
528- int activeCount = 0 ;
529518 for (int index=0 ; index<sd.mg .size (); index++)
530519 {
531520 auto duration = std::chrono::steady_clock::now () - sd.mg [index]->lastRenderClockTime ;
532521 if (duration>sd.mg [index]->renderInterval )
533522 {
534523 if (sd.mg [index]->loopInThread () == 0 )
535524 {
536- activeCount++;
537525 sd.mg [index]->lastRenderClockTime = std::chrono::steady_clock::now ();
538526 }
539527 }
@@ -544,23 +532,25 @@ void renderingThreadFcn()
544532 {
545533 auto &miTemp = sd.mi [miIndex];
546534
547- if (miTemp->cameraSync . check_availability () == false )
535+ if (miTemp->shouldCameraRenderNow == true )
548536 {
549537 // if rendering is already done and not consumed, dont do again
550538 for (int camIndex = 0 ; camIndex<miTemp->offscreenCam .size (); camIndex++)
551539 {
552- if (miTemp->offscreenCam [camIndex]->loopInThread () == 0 )
540+ auto status = miTemp->offscreenCam [camIndex]->loopInThread ();
541+ if (status == 0 )
553542 {
554- activeCount++ ;
555- miTemp->isCameraDataNew = true ;
543+ miTemp-> lastRenderTime = miTemp-> get_d ()-> time ;
544+ miTemp->isCameraDataNew = true ; // Used to indicate that a new data is available for copying into blk output
556545 }
557546 }
547+ miTemp->shouldCameraRenderNow = false ;
558548 miTemp->cameraSync .release ();
549+
559550 }
560551 }
561552 // If there is nothing to render, donot keep spinning while loop
562553 if (sd.signalThreadExit == true ) break ;
563- // if(activeCount == 0) break;
564554 }
565555
566556 // Release visualization resources
@@ -584,16 +574,17 @@ void renderingThreadFcn()
584574static void mdlOutputs (SimStruct *S, int_T tid)
585575{
586576 int miIndex = ssGetIWorkValue (S, MI_IW_IDX);
577+ auto &miTemp = sd.mi [miIndex];
587578
588579 // Copy sensors to output
589580 real_T *y = ssGetOutputPortRealSignal (S, SENSOR_PORT_INDEX);
590581 int_T ny = ssGetOutputPortWidth (S, SENSOR_PORT_INDEX);
591582 int_T index = 0 ;
592583
593- auto nSensors = sd. mi [miIndex] ->si .count ;
584+ auto nSensors = miTemp ->si .count ;
594585 for (int_T i=0 ; i<nSensors; i++)
595586 {
596- vector<double > yVec = sd. mi [miIndex] ->getSensor (i);
587+ vector<double > yVec = miTemp ->getSensor (i);
597588 for (auto elem: yVec)
598589 {
599590 y[index] = elem;
@@ -603,15 +594,29 @@ static void mdlOutputs(SimStruct *S, int_T tid)
603594 }
604595 y[index] = static_cast <double >(nSensors); // last element is a dummy to handle empty sensor case
605596
597+ // Render camera based on the current states. mdlupdate will be called after mdloutputs and update moves the time tk to tk+1
598+ if (miTemp->offscreenCam .size () != 0 )
599+ {
600+ double elapsedTimeSinceRender = miTemp->get_d ()->time - miTemp->lastRenderTime ;
601+ if ( elapsedTimeSinceRender > (miTemp->cameraRenderInterval -0.00001 ) )
602+ {
603+ // maintain camera and physics in sync at required camera sample time
604+ miTemp->shouldCameraRenderNow = true ;
605+ miTemp->cameraSync .acquire (); // blocking till offscreen buffer is rendered
606+
607+ // ssPrintf("sim time=%lf & render time=%lf\n", miTemp->get_d()->time, miTemp->lastRenderTime);
608+ }
609+ }
610+
606611 // Copy camera to output
607612 uint8_T *rgbOut = (uint8_T *) ssGetOutputPortSignal (S, RGB_PORT_INDEX);
608613 real32_T *depthOut = (real32_T *) ssGetOutputPortSignal (S, DEPTH_PORT_INDEX);
609- if (sd. mi [miIndex] ->isCameraDataNew )
614+ if (miTemp ->isCameraDataNew )
610615 {
611616 // avoid unnecessary memcpy. copy only when there is new data. Rest of the time steps, old data will be output
612- sd. mi [miIndex] ->getCameraRGB ((uint8_t *) rgbOut);
613- sd. mi [miIndex] ->getCameraDepth ((float *) depthOut);
614- sd. mi [miIndex] ->isCameraDataNew = false ;
617+ miTemp ->getCameraRGB ((uint8_t *) rgbOut);
618+ miTemp ->getCameraDepth ((float *) depthOut);
619+ miTemp ->isCameraDataNew = false ;
615620 }
616621}
617622
0 commit comments