-
Notifications
You must be signed in to change notification settings - Fork 194
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Connect to a Specific Device using IP address as input #153
base: ros-release
Are you sure you want to change the base?
Connect to a Specific Device using IP address as input #153
Conversation
…idual cameras with IP. In this way, we can connect to multiple cameras easier by specifying their IP adress. Device manager under depthai-python was used to assign static IP addresses to each camera
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the PR.
As of the IP address based access I can accept that. But can you also modify to include MxID based device selection for PoE too ?
And also would need the same changes for stereo_inertial_publisher.cpp in ros2.
As of the launch file. I would pass on that for now. It still limits to 3 devices. If you use the single device launch file and call it multiple times in an another launch file it should still do the same job. So the users can call it the number of devices they have. be it 3 or 10.
…nnect one randomly. Also checked different possibilities to cover all conditional branches and added necessary error prints
@saching13 how about the new commit? Now we have three way of connecting If it looks good, I will bring changes to ROS2 code too. |
@samialperen I'm interested in using this with ROS2. If you push an update to this branch I can test it out because I want to launch multiple OAK-D cameras and specify the IP address for each camera to launch. In my use-case I will associate specific IP addresses with specific top prefixes for further processing in a ROS node. |
@zflat heyo! I will try to bring the changes to ROS2 either tonight or tomorrow night. Stay tuned and thanks for offering testing it out. |
…ult current method) options added to ROS2
@zflat @saching13 ROS2 changes were added with the last commit and tested in ROS2 Foxy. |
@samialperen All looks good. |
…s and tested in noetic. Multi node now is calling stereo inertial node multiple times to give an idea to users how they can use multiple cameras
@saching13 Done! Tested with a single USB in ROS noetic, and it is working fine. I did not have a chance to test multi-launch with multiple cameras since I no longer have the same setup. |
@samialperen I did some initial testing and have some feedback Need to check
|
@zflat heyo! Thanks for the feedback.
|
@samialperen Oops, I meant to write This is what I am logging out after I connect:
That logs "deviceInfo.state: 1" after |
if(useWithIP) // Connecting to a camera with specific IP, requires static IP config beforehand | ||
{ | ||
auto deviceInfo = dai::DeviceInfo(ipAddress); | ||
if(deviceInfo.state == X_LINK_UNBOOTED || deviceInfo.state == X_LINK_BOOTLOADER || deviceInfo.state == X_LINK_FLASH_BOOTED) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The value of deviceInfo.state
is always 0
here so the exception "Could NOT connect to device with IP Address" is always thrown. If we want to check if another process already has a connection, maybe we should do something like this:
if(useWithIP) {
auto connectionInfo = dai::Device::getAllConnectedDevices();
for (auto const& info : connectionInfo)
{
if (info.name == ipAddress && info.state == X_LINK_BOOTED) {
// Throw exception here....
}
}
auto deviceInfo = dai::DeviceInfo(ipAddress);
if(poeMode) {
device = std::make_shared<dai::Device>(pipeline, deviceInfo);
} else {
device = std::make_shared<dai::Device>(pipeline, deviceInfo, usb2Mode);
}
if(device.getDeviceInfo().state == X_LINK_BOOTED) {
std::cout << "Device found with IP Address: " << ipAddress << std::endl;
}
else if(useWithMxId) {
// ...
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@zflat Did you assign a static ip to your camera using depthai device manager? I tested it with my camera and it seems to be working. deviceInfo.state is actually an enum, so if it returns 1, it can take the following values
so 1 probably corresponds to X_LINK_BOOTED
, which kinda tells me that you have not used device manager, because once you use device manager to assign static IP, deviceInfo.state
becomes X_LINK_FLASH_BOOTED.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@zflat Could you try to flash the newest bootloader? I remember I had a problem connecting to my device with IP address before updating the bootloader. If it doesn't solve the issue, I should have OAK (Series 1) POE lying somewhere. I will test it with that guy.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have tried flashing a new bootloader and I just get an error popup and then a message to the terminal that it was cancelled. Sorry I can't be of more help.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@zflat No problem! Lemme give it a try.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@zflat You are right. Somehow, deviceInfo.state
returns 0 once it is not created by get all available devices. 0 means X_LINK_ANY_STATE, so I added that one to if condition and tested it with two cameras at the same time. It should be working fine now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@zflat what was your execution command here ?
if(useWithIP) // Connecting to a camera with specific IP, requires static IP config beforehand | ||
{ | ||
auto deviceInfo = dai::DeviceInfo(ipAddress); | ||
if(deviceInfo.state == X_LINK_ANY_STATE || deviceInfo.state == X_LINK_UNBOOTED || deviceInfo.state == X_LINK_BOOTLOADER || deviceInfo.state == X_LINK_FLASH_BOOTED) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
PoE device can be launched only if it is in Bootloader Mode I think. IIRC.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@saching13 I tested this with POE device too and sometimes it goes to X_LINK_ANY_STATE. Also, if you update the latest bootloader, it takes FLASH_BOOTED, so to be on the safe side, I included all the conditions, but if you think some of them is not necessary, then I will remove unnecessary ones.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is this the case ? @themarpe
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
XLink any state would be an issue querying the information from the device. We should fix that in core. Fo you have a repro @samialperen ?
Flash booted state happens when a pipeline is flashed onto device to run standalone on boot. That is a valid case to then stop that pipeline and start a new one
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@themarpe @saching13 I have OAK-D version 1, OAK-D-PRO-W POE, OAK-D-PRO USB, OAK-D-PRO-W USB. If you can share more context about what is expected from each device (or device type USB vs poe), I can test this one and share the results here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If queried you should see unbooted, bootloader, and booted if already running.
Check protocol for type of connection (usb/tcpip)
} else { | ||
device = std::make_shared<dai::Device>(pipeline, deviceInfo, usb2Mode); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if(useWithIP)
section is already PoE region. you don't need to check for if PoE and else here. Do it only under MxID condition
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Makes a lot of sense.
else if(useWithMxId) // Connecting to a camera with unique MxID | ||
{ | ||
auto deviceInfo = dai::DeviceInfo(mxId); | ||
if(deviceInfo.state == X_LINK_ANY_STATE || deviceInfo.state == X_LINK_UNBOOTED || deviceInfo.state == X_LINK_BOOTLOADER || deviceInfo.state == X_LINK_FLASH_BOOTED) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No need for Flashed_Boot here. it means device is running on it's own using the NOR flash config already.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will test this if it works fine, then I will remove flash booted, but as far as I remember, flashed booted comes up once you update the bootloader.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thoughts ? @themarpe
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@samialperen
Just updating the bootloader should not cause a flash booted state as described in the other comment. I assume you have a pipeline flashed on the device, which is then booted.
Also this code isn't valid. DeviceInfo is just a hokder of information that other functions fill out. Setting mxid to constructor doesn't fill out the state or any other fields.
Use Device.getX device to search for devices and return deviceinfo objects
if(useWithIP) // Connecting to a camera with specific IP, requires static IP config beforehand | ||
{ | ||
auto deviceInfo = dai::DeviceInfo(ipAddress); | ||
if(deviceInfo.state == X_LINK_ANY_STATE || deviceInfo.state == X_LINK_UNBOOTED || deviceInfo.state == X_LINK_BOOTLOADER || deviceInfo.state == X_LINK_FLASH_BOOTED) { | ||
std::cout << "Device found with IP Address: " << ipAddress << std::endl; | ||
if(poeMode) { | ||
device = std::make_shared<dai::Device>(pipeline, deviceInfo); | ||
} else { | ||
device = std::make_shared<dai::Device>(pipeline, deviceInfo, usb2Mode); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same as above
if(deviceInfo.state == X_LINK_ANY_STATE || deviceInfo.state == X_LINK_UNBOOTED || deviceInfo.state == X_LINK_BOOTLOADER || deviceInfo.state == X_LINK_FLASH_BOOTED) { | ||
std::cout << "Connecting to device with MxID : " << mxId << std::endl; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same as above
throw std::runtime_error("\" DepthAI Device with MxId \"" + mxId + "\" is already booted on different process. \""); | ||
if(useWithIP) // Connecting to a camera with specific IP, requires static IP config beforehand | ||
{ | ||
auto deviceInfo = dai::DeviceInfo(ipAddress); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What will happen if useWithIp
is set but ipAddress is not set ?
Same for useWithMxID
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good condition to check. will test and update it.
…mxID but do not specify the addresses.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As discussed in other comments main issue this PR has is that it assumes that DeviceInfo searches for the device. Just creating DeviceInfo object leaves everything else empty (default values, which due to opt. could be any value) and is likely the reason for seeing states such as any state, etc...
To handle this, retrieve a device list of available device using Device::getAvailableDevices() and then check if a specified deviceId or ipAddress/usbPort was found. If so, pass that specific DeviceInfo to the constructor of a Device
CC: @Serafadam |
@themarpe this was my initial plan however, |
I found that |
@samialperen |
Specific functions to retrieve ipv4 could be added. You may open a PR against core |
@themarpe I see. Lemme check deviceInfo.name, if it does not work out, I will open a PR for depthai-core. Thanks! I will keep updating here. |
… of all devices then iterate through them.
Note I think this PR could greatly be simplified. Core already supports the following: And Device constructor also handles the devices's STATE so that can also be removed. |
@themarpe I agree, the last commit was just to check whether everything is working or not. |
ipAddress = LaunchConfiguration('ipAddress', default = 'x') | ||
mxId = LaunchConfiguration('mxId', default = 'x') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it is x
here. you are checking for empty in the code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@saching13 Good catch! I fixed it with the new commit
+1 on this one, would make using multiple cameras (4 in our case :) ) much more reasonable. |
@iliabaranov good to know :) Sorry for the late reply. I hope it will be merged soon. |
…idual cameras with IP. In this way, we can connect to multiple cameras easier by specifying their IP adress. Device manager under depthai-python was used to assign static IP addresses to each camera