Skip to content
Permalink
Browse files

[Orbbec] Added 60fps support and fixed IR gain getter/setter for 2nd …

…gen devices Embedded S and Stereo S. (#189)

Updated OpenNI dependency to newest version 2.3.0.55
  • Loading branch information...
sisiplac authored and jangernert committed Mar 14, 2019
1 parent 9710e98 commit 0731bbced9ce2f5ce3397a343b340b87a848a91e
@@ -231,47 +231,47 @@ void MetriCam2::Cameras::AstraOpenNI::ConnectImpl()
VendorID = dInfo.getUsbVendorId();
ProductID = dInfo.getUsbProductId();

//Check whether the camera has a color channel.
_hasColor = Device.hasSensor(openni::SensorType::SENSOR_COLOR);
if (!_hasColor)
{
if (IsChannelActive((ChannelNames::Color)))
{
log->Warn("This camera does not support the channel \"Color\". Deactivating and removing channel \"Color\"...");
DeactivateChannel(ChannelNames::Color);
}
Channels->Remove(GetChannelDescriptor(ChannelNames::Color));
}

char deviceType[32] = { 0 };
int size = 32;
Device.getProperty(openni::OBEXTENSION_ID_DEVICETYPE, deviceType, &size);
DeviceType = gcnew String(deviceType);
if (DeviceType->StartsWith("Orbbec "))
Model = DeviceType->StartsWith("Orbbec ") ? DeviceType->Substring(7) : DeviceType; //1st gen device types start with string "Orbbec ", 2nd gen devices not.
if (ProductID == 1547 || ProductID == 1544) //2nd gen device types are: Embedded S and Stereo S
{
Model = DeviceType->Substring(7);
if (Model->Contains("Astra"))
_useI2CGain = false;
_irGainMin = IR_Gain_2nd_gen_MIN;
_irGainMax = IR_Gain_2nd_gen_MAX;
_intensityYTranslation = 0;
_depthResolution = Point2i(640, 400);
if (ProductID == 1547)
{
_depthResolution = Point2i(640, 480); //Regular Astra Product
_hasColor = true;
_intensityYTranslation = 16;
_depthFps = 60; //Embedded S is the only model which supports 60fps.
}
else //Prototypes do not contain the keyword "Astra"
else
{
_depthResolution = Point2i(640, 400); //Prototype

if (ProductID == 1547)
{
Model = "Astra embedded S";
}
else if (ProductID == 1544)
{
Model = "Astra stereo S";
}

if (IsChannelActive((ChannelNames::Color)))
{
log->Warn("This camera does not support the channel \"Color\". Deactivating and removing channel \"Color\"...");
DeactivateChannel(ChannelNames::Color);
}
Channels->Remove(GetChannelDescriptor(ChannelNames::Color));
_hasColor = false;
_intensityYTranslation = 0;
_depthFps = 30;
}
}
else
{
_depthResolution = Point2i(640, 480); //Let's try VGA for really unknown camera types.
_hasColor = true; //Let's expect, that the unknown camera has a color channel.
_intensityYTranslation = 0;
else //1st gen device types are: Astra, Astra S, Astra Pro, Astra Mini, Astra Mini S
{
_intensityYTranslation = 16; //1st gen shift between IR and color.
_useI2CGain = true;
_irGainMin = IR_Gain_1st_gen_MIN;
_irGainMax = IR_Gain_1st_gen_MAX;
_depthResolution = Point2i(640, 480);
_depthFps = 30;
}

//Is buggy in OpenNI version 2.3.1.48, so we skip activating the proximity sensor.
@@ -395,66 +395,73 @@ void MetriCam2::Cameras::AstraOpenNI::SetIRFlooderStatus(bool on)

int MetriCam2::Cameras::AstraOpenNI::GetIRGain()
{
#if USE_I2C_GAIN
std::vector<std::string> cmd_r;
const char *argv_r[4] = {};
int i;
XnControlProcessingData I2C;
if (_useI2CGain)
{
std::vector<std::string> cmd_r;
const char *argv_r[4] = {};
int i;
XnControlProcessingData I2C;

argv_r[0] = "i2c";
argv_r[1] = "read";
argv_r[2] = "1";
argv_r[3] = "0x35";
for (i = 0; i < 4; i++)
{
cmd_r.push_back(argv_r[i]);
}

argv_r[0] = "i2c";
argv_r[1] = "read";
argv_r[2] = "1";
argv_r[3] = "0x35";
for (i = 0; i < 4; i++)
unsigned short gain = read_i2c(Device, cmd_r, I2C);
return gain;
}
else
{
cmd_r.push_back(argv_r[i]);
int gain = 0;
int size = 4;
Device.getProperty(openni::OBEXTENSION_ID_IR_GAIN, (uint8_t*)&gain, &size);
return gain;
}

unsigned short gain = read_i2c(Device, cmd_r, I2C);
return gain;
#else
int gain = 0;
int size = 4;
Device.getProperty(openni::OBEXTENSION_ID_IR_GAIN, (uint8_t*)&gain, &size);
return gain;
#endif
}

void MetriCam2::Cameras::AstraOpenNI::SetIRGain(int value)
{
if (value < IR_Gain_MIN)
if (value < _irGainMin)
{
value = IR_Gain_MIN;
value = _irGainMin;
}
else if (value > IR_Gain_MAX)
else if (value > _irGainMax)
{
value = IR_Gain_MAX;
value = _irGainMax;
}
#if USE_I2C_GAIN
std::string buf = string_format("0x%x", value);
std::vector<std::string> cmd_r;
const char *argv_r[5] = {};
int i;
XnControlProcessingData I2C;

argv_r[0] = "i2c";
argv_r[1] = "write";
argv_r[2] = "1";
argv_r[3] = "0x35";
argv_r[4] = buf.c_str();
if (_useI2CGain)
{
std::string buf = string_format("0x%x", value);
std::vector<std::string> cmd_r;
const char *argv_r[5] = {};
int i;
XnControlProcessingData I2C;

argv_r[0] = "i2c";
argv_r[1] = "write";
argv_r[2] = "1";
argv_r[3] = "0x35";
argv_r[4] = buf.c_str();

for (i = 0; i < 5; i++)
for (i = 0; i < 5; i++)
{
cmd_r.push_back(argv_r[i]);
}

write_i2c(Device, cmd_r, I2C);
log->DebugFormat("IR gain is set to: {0}", gcnew String(buf.c_str()));
}
else
{
cmd_r.push_back(argv_r[i]);
int gain = value;
int size = 4;
Device.setProperty(openni::OBEXTENSION_ID_IR_GAIN, (uint8_t*)&gain, size);
}

write_i2c(Device, cmd_r, I2C);
log->DebugFormat("IR gain is set to: {0}", gcnew String(buf.c_str()));
#else
int gain = value;
int size = 4;
Device.setProperty(openni::OBEXTENSION_ID_IR_GAIN, (uint8_t*)&gain, size);
#endif
}

int MetriCam2::Cameras::AstraOpenNI::GetIRExposure()
@@ -572,6 +579,7 @@ void MetriCam2::Cameras::AstraOpenNI::InitDepthStream()
openni::Status rc = DepthStream.create(Device, openni::SENSOR_DEPTH);
openni::VideoMode depthVideoMode = DepthStream.getVideoMode();
depthVideoMode.setResolution(_depthResolution.X, _depthResolution.Y);
depthVideoMode.setFps(_depthFps);
rc = DepthStream.setVideoMode(depthVideoMode);
DepthStream.setMirroringEnabled(false);
if (openni::STATUS_OK != rc)
@@ -1131,7 +1139,6 @@ bool MetriCam2::Cameras::AstraOpenNI::IsDepthFrameValid_NumberNonZeros(FloatCame
return ratio > thresholdPercentage;
}

#if USE_I2C_GAIN
bool atoi2(const char* str, int* pOut)
{
int output = 0;
@@ -1263,5 +1270,4 @@ std::string string_format(const std::string& format, Args ... args)
std::unique_ptr<char[]> buf(new char[size]);
snprintf(buf.get(), size, format.c_str(), args ...);
return std::string(buf.get(), buf.get() + size - 1); // We don't want the '\0' inside
}
#endif
}
@@ -2,24 +2,19 @@
// MetriCam 2 is licensed under the MIT license. See License.txt for full license text.

#pragma once
// When USE_I2C_GAIN is set, then the old, I2C code is used to get/set the IrGain.
// Otherwise, the new Orbbec OpenNI extension is used (which seems still buggy).
#define USE_I2C_GAIN 1

#include <msclr/marshal.h>
#include <PS1080.h>
#include <OpenNI.h>

#if USE_I2C_GAIN
#include <iostream>
#include <vector>
#endif

//Adpated from SimpleViewer of experimental interface
const int IR_Exposure_MAX = 1 << 14;
const int IR_Exposure_MIN = 0;
const int IR_Gain_MIN = 8;
const int IR_Gain_MAX = 63;
const int IR_Gain_1st_gen_MIN = 8;
const int IR_Gain_1st_gen_MAX = 63;
const int IR_Gain_2nd_gen_MIN = 64;
const int IR_Gain_2nd_gen_MAX = 15999;

using namespace System;
using namespace System::ComponentModel;
@@ -31,13 +26,11 @@ using namespace System::Collections::Generic;
using namespace Metrilus::Util;
using namespace Metrilus::Logging;

#if USE_I2C_GAIN
bool atoi2(const char* str, int* pOut);
unsigned short read_i2c(openni::Device& device, std::vector<std::string>& Command, XnControlProcessingData& I2C);
bool write_i2c(openni::Device& device, std::vector<std::string>& Command, XnControlProcessingData& I2C);
template<typename ... Args>
std::string string_format(const std::string& format, Args ... args);
#endif

namespace MetriCam2
{
@@ -274,7 +267,7 @@ namespace MetriCam2
{
inline ParamDesc<int>^ get()
{
ParamDesc<int>^ res = ParamDesc::BuildRangeParamDesc(IR_Gain_MIN, IR_Gain_MAX);
ParamDesc<int>^ res = ParamDesc::BuildRangeParamDesc(_irGainMin, _irGainMax);
res->Unit = "";
res->Description = "IR gain";
res->ReadableWhen = ParamDesc::ConnectionStates::Connected;
@@ -340,8 +333,14 @@ namespace MetriCam2
OrbbecNativeCameraData* _pCamData;
int _vid;
int _pid;
// When USE_I2C_GAIN is set, then the old, I2C code is used to get/set the IrGain.
// Otherwise, the new Orbbec OpenNI extension is used (which seems still buggy).
bool _useI2CGain;
int _irGainMin;
int _irGainMax;
String^ _deviceType;
Point2i _depthResolution;
int _depthFps;
bool _hasColor;
// Compensate for offset between IR and Distance images:
// Translate infrared frame by a certain number of pixels in vertical direction to match infrared with depth image.
@@ -201,14 +201,14 @@
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PrecompiledHeader>Use</PrecompiledHeader>
<AdditionalIncludeDirectories>Z:\external-libraries\Orbbec\OpenNI2\2.3.1.48\windows\Include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>Z:\external-libraries\Orbbec\OpenNI2\2.3.0.55\Include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<TreatWarningAsError>
</TreatWarningAsError>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<Link>
<AdditionalDependencies>OpenNI2.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>Z:\external-libraries\Orbbec\OpenNI2\2.3.1.48\windows\x64-Release</AdditionalLibraryDirectories>
<AdditionalLibraryDirectories>Z:\external-libraries\Orbbec\OpenNI2\2.3.0.55\Lib</AdditionalLibraryDirectories>
<TreatLinkerWarningAsErrors>
</TreatLinkerWarningAsErrors>
<EmbedManagedResourceFile>OrbbecIcon.ico;%(EmbedManagedResourceFile)</EmbedManagedResourceFile>
@@ -227,7 +227,7 @@
</ClCompile>
<Link>
<AdditionalDependencies>OpenNI2.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>Z:\external-libraries\Orbbec\OpenNI2\2.3.1.48\windows\x64-Release</AdditionalLibraryDirectories>
<AdditionalLibraryDirectories>Z:\external-libraries\Orbbec\OpenNI2\2.3.0.55\Lib</AdditionalLibraryDirectories>
<TreatLinkerWarningAsErrors>
</TreatLinkerWarningAsErrors>
<EmbedManagedResourceFile>OrbbecIcon.ico;%(EmbedManagedResourceFile)</EmbedManagedResourceFile>
@@ -296,12 +296,12 @@
<WarningLevel>Level3</WarningLevel>
<PreprocessorDefinitions>WIN32;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<AdditionalIncludeDirectories>Z:\external-libraries\Orbbec\OpenNI2\2.3.1.48\windows\Include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>Z:\external-libraries\Orbbec\OpenNI2\2.3.0.55\Include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<FunctionLevelLinking>true</FunctionLevelLinking>
</ClCompile>
<Link>
<AdditionalDependencies>OpenNI2.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>Z:\external-libraries\Orbbec\OpenNI2\2.3.1.48\windows\x64-Release</AdditionalLibraryDirectories>
<AdditionalLibraryDirectories>Z:\external-libraries\Orbbec\OpenNI2\2.3.0.55\Lib</AdditionalLibraryDirectories>
<LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
<EmbedManagedResourceFile>OrbbecIcon.ico;%(EmbedManagedResourceFile)</EmbedManagedResourceFile>
</Link>
@@ -316,7 +316,7 @@
</ClCompile>
<Link>
<AdditionalDependencies>OpenNI2.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>Z:\external-libraries\Orbbec\OpenNI2\2.3.1.48\windows\x64-Release</AdditionalLibraryDirectories>
<AdditionalLibraryDirectories>Z:\external-libraries\Orbbec\OpenNI2\2.3.0.55\Lib</AdditionalLibraryDirectories>
<LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
<EmbedManagedResourceFile>OrbbecIcon.ico;%(EmbedManagedResourceFile)</EmbedManagedResourceFile>
</Link>
@@ -369,4 +369,4 @@
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
</Project>

0 comments on commit 0731bbc

Please sign in to comment.
You can’t perform that action at this time.