@@ -442,17 +442,7 @@ static void mdlUpdate(SimStruct *S, int_T tid)
442
442
443
443
auto &miTemp = sd.mi [miIndex];
444
444
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
456
446
miTemp->step (uVec);
457
447
}
458
448
@@ -525,15 +515,13 @@ void renderingThreadFcn()
525
515
while (1 )
526
516
{
527
517
// Visualization window(s)
528
- int activeCount = 0 ;
529
518
for (int index=0 ; index<sd.mg .size (); index++)
530
519
{
531
520
auto duration = std::chrono::steady_clock::now () - sd.mg [index]->lastRenderClockTime ;
532
521
if (duration>sd.mg [index]->renderInterval )
533
522
{
534
523
if (sd.mg [index]->loopInThread () == 0 )
535
524
{
536
- activeCount++;
537
525
sd.mg [index]->lastRenderClockTime = std::chrono::steady_clock::now ();
538
526
}
539
527
}
@@ -544,23 +532,25 @@ void renderingThreadFcn()
544
532
{
545
533
auto &miTemp = sd.mi [miIndex];
546
534
547
- if (miTemp->cameraSync . check_availability () == false )
535
+ if (miTemp->shouldCameraRenderNow == true )
548
536
{
549
537
// if rendering is already done and not consumed, dont do again
550
538
for (int camIndex = 0 ; camIndex<miTemp->offscreenCam .size (); camIndex++)
551
539
{
552
- if (miTemp->offscreenCam [camIndex]->loopInThread () == 0 )
540
+ auto status = miTemp->offscreenCam [camIndex]->loopInThread ();
541
+ if (status == 0 )
553
542
{
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
556
545
}
557
546
}
547
+ miTemp->shouldCameraRenderNow = false ;
558
548
miTemp->cameraSync .release ();
549
+
559
550
}
560
551
}
561
552
// If there is nothing to render, donot keep spinning while loop
562
553
if (sd.signalThreadExit == true ) break ;
563
- // if(activeCount == 0) break;
564
554
}
565
555
566
556
// Release visualization resources
@@ -584,16 +574,17 @@ void renderingThreadFcn()
584
574
static void mdlOutputs (SimStruct *S, int_T tid)
585
575
{
586
576
int miIndex = ssGetIWorkValue (S, MI_IW_IDX);
577
+ auto &miTemp = sd.mi [miIndex];
587
578
588
579
// Copy sensors to output
589
580
real_T *y = ssGetOutputPortRealSignal (S, SENSOR_PORT_INDEX);
590
581
int_T ny = ssGetOutputPortWidth (S, SENSOR_PORT_INDEX);
591
582
int_T index = 0 ;
592
583
593
- auto nSensors = sd. mi [miIndex] ->si .count ;
584
+ auto nSensors = miTemp ->si .count ;
594
585
for (int_T i=0 ; i<nSensors; i++)
595
586
{
596
- vector<double > yVec = sd. mi [miIndex] ->getSensor (i);
587
+ vector<double > yVec = miTemp ->getSensor (i);
597
588
for (auto elem: yVec)
598
589
{
599
590
y[index] = elem;
@@ -603,15 +594,29 @@ static void mdlOutputs(SimStruct *S, int_T tid)
603
594
}
604
595
y[index] = static_cast <double >(nSensors); // last element is a dummy to handle empty sensor case
605
596
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
+
606
611
// Copy camera to output
607
612
uint8_T *rgbOut = (uint8_T *) ssGetOutputPortSignal (S, RGB_PORT_INDEX);
608
613
real32_T *depthOut = (real32_T *) ssGetOutputPortSignal (S, DEPTH_PORT_INDEX);
609
- if (sd. mi [miIndex] ->isCameraDataNew )
614
+ if (miTemp ->isCameraDataNew )
610
615
{
611
616
// 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 ;
615
620
}
616
621
}
617
622
0 commit comments