I'm using Pylon SDK in my project. It's a SDK for Basler cameras.
I'm calling gimbalControl
function in an infinite while loop in the main
function.
In gimbalControl
, I need to define variables and initialize the gimbal parts. Afterwards, I use those initialized and defined things in the rest of the function. Following is a sample of my code clarifying the problem.
void gimbalControl(void)
{
try
{
// Only executed in the first iteration
if(!gimbalInitialized)
{
setupGimbal();
configConnection();
PylonInitialize();
// Create an instant camera object with the camera device found first.
CInstantCamera camera(CTlFactory::GetInstance().CreateFirstDevice());
// Open the camera before accessing any parameters
camera.Open();
// Start the grabbing of images
camera.StartGrabbing();
gimbalInitialized = true;
}
else
{
// Wait for an image and then retrieve it. A timout of 5000 ms is used.
camera.RetrieveResult(5000, ptrGrabResult, TimeoutHandling_ThrowException); // CAUSES ERROR
// Image not grabbed successfully?
if (!ptrGrabResult->GrabSucceeded())
{
cout << "Cannot capture a frame from video stream" << endl;
}
}
catch(...) // Catch all unhandled exceptions
{
printf("ERROR IN CAMERA CONNECTION\n");
}
}
I tried to make this module class-based but I didn't know how to declare camera in the class to be used later in the object. Actually, I don't know what this kind of camera
declaration is!
When I compile this code I got an error that camera was not declared in this scope
. Question 1 : How can I define camera once in this infinite loop without raising this error?
Question 2 : How can I declare camera
as a private variable inside a class?
One approach is to make camera
static outside the try
block:
static CInstantCamera camera(CTlFactory::GetInstance().CreateFirstDevice());
try {
...
} catch (...) {
...
}
This ensures that camera
object gets initialized only once, and stays accessible on both sides of the else
in the conditional.
To declare camera
in your class, put CTlFactory::GetInstance().CreateFirstDevice()
in the initializer list:
class MyClass {
private:
CInstantCamera camera;
public:
MyClass() : camera(CTlFactory::GetInstance().CreateFirstDevice()) {
}
};
camera
is just a regular initialization. In this case, you're just calling the constructor on CInstantCamera
that takes whatever type CTlFactory::GetInstance().CreateFirstDevice()
is as the only argument.
Scopes for all intents and purposes define the lifetime of objects. One object cannot realistically talk to another in a different scope, unless they share a parent scope. In this case, camera
is defined within the scope of the first if
conditional block scope, but you reference it in the else
conditional block scope.
void gimbalControl(void)
{
// scope #1
try
{
// scope #2 (inherits #1)
if(!gimbalInitialized)
{
// scope #3 (inherits #1, #2)
}
else
{
// scope #4 (inherits #1, #2)
}
}
catch(...)
{
// scope #5 (inherits #1)
}
}
Notice how scope 4 only inherits 1 and 2 , and not 3 ? They are in the same parent level scope, so they do not have the same lifetimes. Objects cannot talk to each other (reasonably) within these scopes.
The solution, is to just initialize camera
in scope 2 . Since you are calling this in a loop, you will need to make the declaration static
, so that it's not constructed during each call, just the first one.
References - Scope , Storage Duration - see: static
Simply stated, if your main calls gimbalControl() in a loop, you'll have to declare whatever variable you want to only have once outside of gimbalControl. Either do it in main before the loop:
int main(){
int myVar=0; //only declareded once
while(true){
gimbalControl();
}
}
or declare them as global variables. If you declare it in gimbalControl and call gimballControl multiple times, each time you call gimbalControll it will delcare it.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.