38 #ifndef WIN32_LEAN_AND_MEAN 39 #define WIN32_LEAN_AND_MEAN 1 60 #define strcasecmp _stricmp 67 std::vector<imu::Info> sensor_infos;
68 std::vector<imu::Config> sensor_configs;
69 uint32_t sensor_samplesPerMessage = 0;
70 uint32_t sensor_maxSamplesPerMessage = 0;
72 void usage(
const char *programNameP)
74 std::cerr <<
"USAGE: " << programNameP <<
" [<options>]" << std::endl;
75 std::cerr <<
"Where <options> are:" << std::endl;
76 std::cerr <<
"\t-a <ip_address> : IPV4 address (default=10.66.171.21)" << std::endl;
77 std::cerr <<
"\t-q : query and report IMU configuration" << std::endl;
78 std::cerr <<
"\t-f : store IMU configuration in non-volatile flash" << std::endl;
79 std::cerr <<
"\t-s <samples> : set IMU samples-per-message" << std::endl;
80 std::cerr <<
"\t-c \"<sensor_config>\" : IMU sensor configuration string\n" << std::endl;
81 std::cerr <<
"And \"<sensor_config>\" is of the following form:" << std::endl;
82 std::cerr <<
"\t\"<sensor_name> <enabled> <rate_table_index> <range_table_index>\"\n" << std::endl;
83 std::cerr <<
"For example, to enable the accelerometer, and have it use rate index 1 and range index 2:\n" << std::endl;
84 std::cerr <<
"\t-c \"accelerometer true 1 2\"\n" << std::endl;
85 std::cerr <<
"Multiple \"-c\" options may be specified to configure more than 1 sensor\n" << std::endl;
86 std::cerr <<
"Please note that small values for samples-per-message combined with high IMU sensor rates" << std::endl;
87 std::cerr <<
"may interfere with the acquisition and transmission of image and lidar data, if applicable" << std::endl;
92 bool imuInfoByName(
const std::string& name,
imu::Info& info)
94 std::vector<imu::Info>::const_iterator it = sensor_infos.begin();
96 for(; it != sensor_infos.end(); ++it)
97 if (name == (*it).name) {
110 std::string currentAddress =
"10.66.171.21";
111 int32_t user_samplesPerMessage = 0;
113 bool storeInFlash =
false;
114 std::vector<std::string> cli_configs;
122 while(-1 != (c =
getopt(argc, argvPP,
"a:s:c:qf")))
124 case 'a': currentAddress = std::string(
optarg);
break;
125 case 's': user_samplesPerMessage = atoi(
optarg);
break;
126 case 'q': query =
true;
break;
127 case 'f': storeInFlash =
true;
break;
128 case 'c': cli_configs.push_back(
optarg);
break;
129 default:
usage(*argvPP);
break;
136 if (user_samplesPerMessage < 0) {
137 std::cerr <<
"Invalid samples-per-message: " << user_samplesPerMessage << std::endl;
144 if (0 == cli_configs.size() && 0 == user_samplesPerMessage)
151 if (NULL == channelP) {
152 std::cerr <<
"Failed to establish communications with \"" << currentAddress <<
"\"" << std::endl;
168 std::cout <<
"Version information:\n";
169 std::cout <<
"\tAPI build date : " << v.
apiBuildDate <<
"\n";
170 std::cout <<
"\tAPI version : 0x" << std::hex << std::setw(4) << std::setfill(
'0') << v.
apiVersion <<
"\n";
172 std::cout <<
"\tFirmware version : 0x" << std::hex << std::setw(4) << std::setfill(
'0') << v.
sensorFirmwareVersion <<
"\n";
175 std::cout <<
"\tFPGA DNA : 0x" << std::hex << v.
sensorFpgaDna <<
"\n";
176 std::cout << std::dec;
183 std::cerr <<
"IMU support requires sensor firmware version v2.3 or greater, sensor is " <<
191 status = channelP->
getImuInfo(sensor_maxSamplesPerMessage,
197 status = channelP->
getImuConfig(sensor_samplesPerMessage, sensor_configs);
204 std::cout <<
"\nMax IMU samples-per-message: " << sensor_maxSamplesPerMessage <<
"\n";
205 std::cout << sensor_infos.size () <<
" IMU sensors:\n";
206 for(uint32_t i=0; i<sensor_infos.size(); i++) {
210 std::cout <<
"\t" << m.
name <<
":\n";
211 std::cout <<
"\t\tdevice: " << m.
device <<
"\n";
212 std::cout <<
"\t\tunits : " << m.
units <<
"\n";
213 std::cout <<
"\t\trates : " << m.
rates.size() <<
": rate (Hz), bandwidthCutoff (Hz)\n";
214 for (uint32_t j = 0; j < m.
rates.size(); j++)
215 std::cout <<
"\t\t\t\t" << j <<
": " << std::fixed << std::setprecision(1) << m.
rates[j].sampleRate <<
"," <<
216 std::fixed << std::setprecision(3) << m.
rates[j].bandwidthCutoff <<
"\n";
217 std::cout <<
"\t\tranges: " << m.
ranges.size() <<
": range (+/- " << m.
units <<
"), resolution (" << m.
units <<
")\n";
218 for (uint32_t j = 0; j < m.
ranges.size(); j++)
219 std::cout <<
"\t\t\t\t" << j <<
": " << std::fixed << std::setprecision(1) << m.
ranges[j].range <<
", " <<
220 std::fixed << std::setprecision(6) << m.
ranges[j].resolution <<
"\n";
223 std::cout <<
"\nCurrent IMU configuration:\n";
224 std::cout <<
"\t-s " << sensor_samplesPerMessage <<
" ";
225 for(uint32_t i=0; i<sensor_configs.size(); i++) {
229 std::cout <<
"-c \"" << c.
name <<
" " << (c.
enabled ?
"true" :
"false") <<
" " <<
238 if (user_samplesPerMessage > 0 || cli_configs.size() > 0) {
240 std::vector<imu::Config> user_configs;
241 bool configValid =
true;
243 if (user_samplesPerMessage > static_cast<int32_t>(sensor_maxSamplesPerMessage)) {
244 std::cerr <<
"Invalid samples-per-message " << user_samplesPerMessage <<
", valid values are in [1," << sensor_maxSamplesPerMessage <<
"]" << std::endl;
251 for(uint32_t i=0; i<cli_configs.size(); i++) {
253 char nameP[32] = {0};
254 char enabledP[32] = {0};
258 if (4 != sscanf(cli_configs[i].c_str(),
"%31s %31s %d %d",
259 nameP, enabledP, &rate, &range)) {
260 std::cerr <<
"Malformed IMU config: \"" << cli_configs[i] <<
"\"" << std::endl;
265 if (0 != strcasecmp(enabledP,
"true") &&
266 0 != strcasecmp(enabledP,
"false")) {
267 std::cerr <<
"Malformed <enabled> string \"" << enabledP <<
"\", must be one of \"true\" or \"false\"" << std::endl;
276 if (
false == imuInfoByName(nameP, info)) {
277 std::cerr <<
"Unknown <sensor_name> \"" << nameP <<
"\", query config for a list of valid names" << std::endl;
285 if (rate < 0 || rate >= static_cast<int32_t>(info.
rates.size())) {
286 std::cerr <<
"Invalid rate table index " << rate <<
" for \"" << nameP <<
"\", valid indices are in [0," << (info.
rates.size() - 1) <<
"]" << std::endl;
289 if (range < 0 || range >= static_cast<int32_t>(info.
ranges.size())) {
290 std::cerr <<
"Invalid range table index " << range <<
" for \"" << nameP <<
"\", " <<
291 "valid indices are in [0," << (info.
ranges.size() - 1) <<
"]" << std::endl;
295 if (
false == configValid)
302 c.
name = std::string(nameP);
303 c.
enabled = (0 == strcasecmp(enabledP,
"true"));
307 user_configs.push_back(c);
310 if (
false == configValid)
311 std::cerr <<
"Errors exist in configuration, aborting" << std::endl;
314 user_samplesPerMessage,
319 std::cout <<
"IMU configuration updated successfully\n";
std::vector< RangeEntry > ranges
static const char * statusString(Status status)
uint64_t sensorHardwareMagic
static Channel * Create(const std::string &sensorAddress)
std::string sensorFirmwareBuildDate
virtual Status getVersionInfo(system::VersionInfo &v)=0
virtual Status getImuConfig(uint32_t &samplesPerMessage, std::vector< imu::Config > &c)=0
int getopt(int argc, char **argv, char *opts)
virtual Status setImuConfig(bool storeSettingsInFlash, uint32_t samplesPerMessage, const std::vector< imu::Config > &c)=0
std::vector< RateEntry > rates
static CRL_CONSTEXPR Status Status_Ok
VersionType sensorFirmwareVersion
static void Destroy(Channel *instanceP)
int main(int argc, char **argvPP)
virtual Status getImuInfo(uint32_t &maxSamplesPerMesage, std::vector< imu::Info > &info)=0
uint64_t sensorHardwareVersion