Closed AustinYuAo closed 12 months ago
Did you find any reason for this? I also suffer this issue by now.
The position values are indeed different, which suggest that you use a different coordinate system. For example, NDI prints StylusTipToTracker, while you are displaying StylusToTracker position in your Plus test application.
There is no standard order for quaternion components, so a different component order may be be fine (as long as it is used consistently).
If you post a link to your Plus configuration and source code of your test application then we can tell why you see different values.
@busyyang In fact, I didn't solve this problem at that time; instead, I used the official NDI code. @lassoan Thank you very much for your response. At that time, based on the example from the link[https://github.com/PlusToolkit/ndicapi/blob/fb6213a4a40de44bee62785397f890b261e02a38/Applications/ndiBasicExample.cxx#L48] , I wrote the test code as follows.
// A simple program that connects to an NDI tracker
//----------------------------------------------------------------------------
bool ParallelProbe(ndicapi& outDevice, bool checkDSR)
{
const int MAX_SERIAL_PORT_NUMBER = 20; // the serial port is almost surely less than this number
std::vector
return false;
}
struct ndicapi;
int main() { bool checkDSR = false; ndicapi device(nullptr); const char name(nullptr);
if (2 > 1)
name = "C:/Users/Au/Desktop/NDIPolaris/measuringTool.rom";
else
{
ParallelProbe(device, checkDSR);
/* ParallelProbe(device,argc > 1 ? argv[1]: 0, checkDSR);*/
{
const int MAX_SERIAL_PORTS = 20;
for (int i = 0; i < MAX_SERIAL_PORTS; ++i)
{
name = ndiSerialDeviceName(i);
int result = ndiSerialProbe(name, checkDSR);
if (result == NDI_OKAY)
{
break;
}
}
}
}
if (name != nullptr)
{
device = ndiOpenSerial(name);
}
if (device != nullptr)
{
const char* reply = ndiCommand(device, "INIT:");
if (strncmp(reply, "ERROR", strlen(reply)) == 0 || ndiGetError(device) != NDI_OKAY)
{
std::cerr << "Error when sending command: " << ndiErrorString(ndiGetError(device)) << std::endl;
return EXIT_FAILURE;
}
reply = ndiCommand(device, "COMM:%d%03d%d", NDI_115200, NDI_8N1, NDI_NOHANDSHAKE);
// Add your own commands here!!!
LoadToolFromFile(0, "C:/Users/Au/Desktop/NDIPolaris/measuringTool.rom");
std::cout << "Starting tracking..." << std::endl;
StartTracking(true);
std::cout << "Tracking..." << std::endl;
QuaternionTransformStruct* toolTransform[2];
while (1)
{
Sleep(250);
if (UpdateTransforms())
{
toolTransform[0] = GetQuaternionTransform(0);
if (toolTransform[0] != NULL && toolTransform[0]->status == 0)
{
printf("q0: %lf\nq1: %lf\nq2: %lf\nq3: %lf\nx: %lf\ny: %lf\nz: %lf\n\n", toolTransform[0]->q0,
toolTransform[0]->q1,
toolTransform[0]->q2,
toolTransform[0]->q3,
toolTransform[0]->x,
toolTransform[0]->y,
toolTransform[0]->z);
}
toolTransform[1] = GetQuaternionTransform(1);
delete toolTransform[0];
delete toolTransform[1];
}
}
printf("Stoping tracking...\n");
StopTracking();
ndiCloseSerial(device);
}
return EXIT_SUCCESS;
}
I would greatly appreciate it if you could help me solve this problem.
Hi @AustinYuAo, I have solved this problem, the reason is that I mixed the rom files in my test code and NDI official tool. :) When I use the same rom file, the result the same with NDI official tool. And I use the NDI Capture from NDI Toolbox 5.002.022 if you would like to know.
Actually, the NDI Vega is used in my project, so I modified the ndiBasicExample.cxx to apply the tcpip communication. Here is the code if it can help you:
// A simple program that connects to an NDI tracker
#include <ndicapi.h>
#include <cstring>
#include <vector>
#include <iostream>
void _check_for_ndi_errors(ndicapi* device, const char* command)
{
int code = ndiGetError(device);
if (code != NDI_OKAY)
{
ndiCloseNetwork(device);
std::cout << "Error when " << command << " The Error was: " << ndiErrorString(code) << std::endl;
exit(-2);
}
}
int main()
{
std::vector<const char*> sroms = {
"data/8700339.rom"
};
std::vector<int> port_handles;
const char* hostname = "169.254.190.4";
int port = 8765;
ndicapi* device = ndiOpenNetwork(hostname, port);
if (!device)
{
std::cout << "No NDI Device fond!" << std::endl;
}
ndiCommand(device, "INIT:");
_check_for_ndi_errors(device, "Sending INIT command");
// free ports that are waiting to be freed
ndiCommand(device, "PHSR:01");
int number_of_tools = ndiGetPHSRNumberOfHandles(device);
for (int i = 0; i < number_of_tools; i++)
{
int port_handle = ndiGetPHSRHandle(device, i);
ndiCommand(device, "PHF:%02X", port_handle);
_check_for_ndi_errors(device, "free port handle");
}
for (size_t i = 0; i < sroms.size(); i++)
{
ndiCommand(device, "PHRQ:*********1****");
_check_for_ndi_errors(device, "PHRQ");
int port_handle = ndiGetPHRQHandle(device);
_check_for_ndi_errors(device, "ndiGetPHRQHandle");
port_handles.push_back(port_handle);
ndiPVWRFromFile(device, port_handle, const_cast<char*>(sroms[i]));
_check_for_ndi_errors(device, "ndiPVWRFromFile");
}
ndiCommand(device, "PHSR:01");
_check_for_ndi_errors(device, "PHSR:01");
// init ports
//ndiCommand(device, "PHSR:02");
for (size_t i = 0; i < sroms.size(); i++)
{
ndiCommand(device, "PINIT:%02X", port_handles[i]);
_check_for_ndi_errors(device, "PINIT");
ndiCommand(device, "PENA:%02XD", port_handles[i]);
_check_for_ndi_errors(device, "PENA");
}
// start tracking
ndiCommand(device, "TSTART:");
_check_for_ndi_errors(device, "start tracking");
// get 100 transforms
int x = 100;
while (x--)
{
for (auto port_handle:port_handles)
{
ndiCommand(device, "TX:0801");
_check_for_ndi_errors(device, "TX:0801");
unsigned long frame_number = ndiGetTXFrame(device, port_handle);
_check_for_ndi_errors(device, "ndiGetTXFrame");
double transform[8] = { 0 };
ndiGetTXTransform(device, port_handle, transform);
_check_for_ndi_errors(device, "ndiGetTXTransform");
printf("Transform: %.3f,%.3f,%.3f,%.3f,%.3f,%.3f,%.3f,%.3f\n",
transform[0], transform[1], transform[2], transform[3],
transform[4], transform[5], transform[6], transform[7]);
}
Sleep(50);
}
}
I fond the scikit-surgerynditracker used the ndicapi as backend. The code is very clear to use NDI device. If you are familar with python, this repo is your friend too.
The huge advantage of Plus over scikit-surgerynditracker is that Plus can acquire data from multiple sources (e.g., tracking and imaging) in a single process, tightly synchronized, at high frame rate, utilizing several CPU cores.
Thanks very much for your reply. After reading this example, I have written a test program. However, when I placed tool in a fixed position, I found a problem. The quaternion value of tool obtained by the test application was different from that obtained by the NDI official application. I took two photos, one is the result of NDI and the other is the result of test program. You can find that the quaternion values in the test program seem to be in a different order, comparing to the quaternion values in the official NDI application, and the x、y、z values are also different.