<commit_before>/** \file    bib_ref_to_codes_tool.cc
 *  \brief   A tool for converting bible references to numeric codes.
 *  \author  Dr. Johannes Ruscheinski
 */

/*
    Copyright (C) 2015, Library of the University of Tübingen

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU Affero General Public License as
    published by the Free Software Foundation, either version 3 of the
    License, or (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Affero General Public License for more details.

    You should have received a copy of the GNU Affero General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
#include <fstream>
#include <iostream>
#include <string>
#include <unordered_map>
#include <cctype>
#include <cstdlib>
#include <cstring>
#include "BibleReferenceParser.h"
#include "MapIO.h"
#include "RegexMatcher.h"
#include "StringUtil.h"
#include "util.h"

std::string InsertSpaceAtFirstLetterDigitBoundary(const std::string &s) {
    if (s.empty())
	return s;

    std::string retval;
    bool found_first_boundary(false);
    auto ch(s.cbegin());
    retval += *ch;
    while (++ch != s.cend()) {
	if (not found_first_boundary and (std::isalpha(*(ch - 1)) and std::isdigit(*ch))) {
	    found_first_boundary = true;
	    retval += ' ';
	}

	retval += *ch;
    }

    return retval;
}

// Squeezes out spaces after a leading number, e.g. "1. mos" => "1.mos" or "1 mos" => "1mos".
std::string CanoniseLeadingNumber(const std::string &bib_ref_candidate) {
    static const RegexMatcher * const matcher(RegexMatcher::RegexMatcherFactory("^\\d\\.?\\s+\\S+"));
    std::string err_msg;
    if (not matcher->matched(bib_ref_candidate, &err_msg)) {
        if (not err_msg.empty())
            Error("unexpected reg ex error: " + err_msg);
        return bib_ref_candidate;
    }

    std::string ordinal_string;
    ordinal_string = bib_ref_candidate[0];
    size_t rest_start(1);
    if (bib_ref_candidate[1] == '.') {
        ordinal_string += '.';
        ++rest_start;
    }

    while (isspace(bib_ref_candidate[rest_start]))
        ++rest_start;

    return ordinal_string + bib_ref_candidate.substr(rest_start);
}

void SplitIntoBookAndChaptersAndVerses(const std::string &bib_ref_candidate, std::string * const book_candidate,
                                       std::string * const chapters_and_verses_candidate)
{
    book_candidate->clear();
    chapters_and_verses_candidate->clear();

    const size_t len(bib_ref_candidate.length());
    if (len <= 3)
        *book_candidate = bib_ref_candidate;
    else if (isdigit(bib_ref_candidate[len - 1])
             or (isalpha(bib_ref_candidate[len - 1]) and isdigit(bib_ref_candidate[len - 2])))
    {
        const size_t last_space_pos(bib_ref_candidate.rfind(' '));
        if (last_space_pos == std::string::npos)
            *book_candidate = bib_ref_candidate;
        else {
            *book_candidate = bib_ref_candidate.substr(0, last_space_pos);
            *chapters_and_verses_candidate = bib_ref_candidate.substr(last_space_pos + 1);
        }
    } else
        *book_candidate = bib_ref_candidate;
}

void Usage() {
    std::cerr << "usage: " << progname << " [--debug|--query] bible_reference_candidate\n";
    std::cerr << "          books_of_the_bible_to_code_map\n";
    std::cerr << "          books_of_the_bible_to_canonical_form_map pericopes_to_codes_map\n";
    std::cerr << '\n';
    std::cerr << "          When --debug has been specified additional tracing output will be generated.\n";
    std::cerr << "          When --query has been specified SOLR search queries will be output.\n";
    std::exit(EXIT_FAILURE);
}

int main(int argc, char **argv) {
    progname = argv[0];

    bool verbose(false), generate_solr_query(false);

    if (argc == 6) {
        if (std::strcmp(argv[1], "--debug") == 0)
            verbose = true;
        else if (std::strcmp(argv[1], "--query") == 0)
            generate_solr_query = true;
        else
            Usage();
        ++argv, --argc;
    }

    if (argc != 5)
        Usage();

    //
    // Deal with pericopes first...
    //

    std::unordered_multimap<std::string, std::string> pericopes_to_codes_map;
    MapIO::DeserialiseMap(argv[4], &pericopes_to_codes_map);

    std::string bib_ref_candidate(StringUtil::Trim(StringUtil::ToLower(argv[1])));
    StringUtil::CollapseWhitespace(&bib_ref_candidate);

    const auto begin_end(pericopes_to_codes_map.equal_range(bib_ref_candidate));
    if (begin_end.first != begin_end.second) {
        if (verbose)
            std::cerr << "Found a pericope to codes mapping.\n";
        std::string query;
        for (auto pair(begin_end.first); pair != begin_end.second; ++pair) {
            if (generate_solr_query) {
                if (not query.empty())
                    query += ' ';
                query += pair->first + "_" + pair->second;
            } else
                std::cout << pair->second << '\n';
        }
        if (generate_solr_query)
            std::cout << query << '\n';

        return EXIT_SUCCESS;
    }

    //
    // ...now deal w/ ordinary references.
    //

    bib_ref_candidate = CanoniseLeadingNumber(InsertSpaceAtFirstLetterDigitBoundary(
                            StringUtil::RemoveChars(" \t", &bib_ref_candidate)));
    std::string book_candidate, chapters_and_verses_candidate;
    SplitIntoBookAndChaptersAndVerses(bib_ref_candidate, &book_candidate, &chapters_and_verses_candidate);
    if (verbose) {
        std::cerr << "book_candidate = \"" << book_candidate << "\"\n";
        std::cerr << "chapters_and_verses_candidate = \"" << chapters_and_verses_candidate << "\"\n";
    }

    // Map from noncanonical bible book forms to the canonical ones:
    std::unordered_map<std::string, std::string> books_of_the_bible_to_canonical_form_map;
    MapIO::DeserialiseMap(argv[3], &books_of_the_bible_to_canonical_form_map);
    const auto non_canonical_form_and_canonical_form(books_of_the_bible_to_canonical_form_map.find(book_candidate));
    if (non_canonical_form_and_canonical_form != books_of_the_bible_to_canonical_form_map.end()) {
        if (verbose)
            std::cerr << "Replacing \"" << book_candidate << "\" with \""
                      << non_canonical_form_and_canonical_form->second << "\".\n";
        book_candidate = non_canonical_form_and_canonical_form->second;
    }

    std::unordered_map<std::string, std::string> bible_books_to_codes_map;
    MapIO::DeserialiseMap(argv[2], &bible_books_to_codes_map);
    const auto bible_book_and_code(bible_books_to_codes_map.find(book_candidate));
    if (bible_book_and_code == bible_books_to_codes_map.end()) {
        if (verbose)
            std::cerr << "No mapping from \"" << book_candidate << "\" to a book code was found!\n";

        return EXIT_FAILURE; // Unknown bible book!
    }

    const std::string book_code(bible_book_and_code->second);
    if (verbose)
        std::cerr << "book code = \"" << book_code << "\"\n";
    if (chapters_and_verses_candidate.empty()) {
        if (generate_solr_query)
            std::cout << (book_code + "00000") << '_' << (book_code + "99999") << '\n';
        else
            std::cout << book_code << "00000:" << book_code << "99999" << '\n';

        return EXIT_SUCCESS;
    }

    std::set<std::pair<std::string, std::string>> start_end;
    if (not ParseBibleReference(chapters_and_verses_candidate, book_code, &start_end)) {
        if (verbose)
            std::cerr << "The parsing of \"" << chapters_and_verses_candidate
                      << "\" as chapters and verses failed!\n";
        return EXIT_FAILURE;
    }

    std::string query;
    for (const auto &pair : start_end) {
        if (generate_solr_query) {
            if (not query.empty())
                query += ' ';
            query += pair.first + "_" + pair.second;
        } else
            std::cout << pair.first << ':' << pair.second << '\n';
    }
    if (generate_solr_query)
        std::cout << query << '\n';
}
<commit_msg>Preliminary support for bible book ranges.<commit_after>/** \file    bib_ref_to_codes_tool.cc
 *  \brief   A tool for converting bible references to numeric codes.
 *  \author  Dr. Johannes Ruscheinski
 */

/*
    Copyright (C) 2015, Library of the University of Tübingen

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU Affero General Public License as
    published by the Free Software Foundation, either version 3 of the
    License, or (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Affero General Public License for more details.

    You should have received a copy of the GNU Affero General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
#include <fstream>
#include <iostream>
#include <string>
#include <unordered_map>
#include <cctype>
#include <cstdlib>
#include <cstring>
#include "BibleReferenceParser.h"
#include "MapIO.h"
#include "RegexMatcher.h"
#include "StringUtil.h"
#include "util.h"

std::string InsertSpaceAtFirstLetterDigitBoundary(const std::string &s) {
    if (s.empty())
	return s;

    std::string retval;
    bool found_first_boundary(false);
    auto ch(s.cbegin());
    retval += *ch;
    while (++ch != s.cend()) {
	if (not found_first_boundary and (std::isalpha(*(ch - 1)) and std::isdigit(*ch))) {
	    found_first_boundary = true;
	    retval += ' ';
	}

	retval += *ch;
    }

    return retval;
}

// Squeezes out spaces after a leading number, e.g. "1. mos" => "1.mos" or "1 mos" => "1mos".
std::string CanoniseLeadingNumber(const std::string &bible_reference_candidate) {
    static const RegexMatcher * const matcher(RegexMatcher::RegexMatcherFactory("^\\d\\.?\\s+\\S+"));
    std::string err_msg;
    if (not matcher->matched(bible_reference_candidate, &err_msg)) {
        if (not err_msg.empty())
            Error("unexpected reg ex error: " + err_msg);
        return bible_reference_candidate;
    }

    std::string ordinal_string;
    ordinal_string = bible_reference_candidate[0];
    size_t rest_start(1);
    if (bible_reference_candidate[1] == '.') {
        ordinal_string += '.';
        ++rest_start;
    }

    while (isspace(bible_reference_candidate[rest_start]))
        ++rest_start;

    return ordinal_string + bible_reference_candidate.substr(rest_start);
}

void SplitIntoBookAndChaptersAndVerses(const std::string &bible_reference_candidate, std::string * const book_candidate,
                                       std::string * const chapters_and_verses_candidate)
{
    book_candidate->clear();
    chapters_and_verses_candidate->clear();

    const size_t len(bible_reference_candidate.length());
    if (len <= 3)
        *book_candidate = bible_reference_candidate;
    else if (isdigit(bible_reference_candidate[len - 1])
             or (isalpha(bible_reference_candidate[len - 1]) and isdigit(bible_reference_candidate[len - 2])))
    {
        const size_t last_space_pos(bible_reference_candidate.rfind(' '));
        if (last_space_pos == std::string::npos)
            *book_candidate = bible_reference_candidate;
        else {
            *book_candidate = bible_reference_candidate.substr(0, last_space_pos);
            *chapters_and_verses_candidate = bible_reference_candidate.substr(last_space_pos + 1);
        }
    } else
        *book_candidate = bible_reference_candidate;
}

/** \brief Map from noncanonical bible book forms to the canonical ones.
 *  \return The mapped name or, if no mapping was found, "bible_book_candidate".
 */
std::string CanoniseBibleBook(const bool verbose, const std::string &books_of_the_bible_to_canonical_form_map_filename,
			      const std::string &bible_book_candidate)
{
    std::unordered_map<std::string, std::string> books_of_the_bible_to_canonical_form_map;
    MapIO::DeserialiseMap(books_of_the_bible_to_canonical_form_map_filename, &books_of_the_bible_to_canonical_form_map);
    const auto non_canonical_form_and_canonical_form(books_of_the_bible_to_canonical_form_map.find(bible_book_candidate));
    if (non_canonical_form_and_canonical_form != books_of_the_bible_to_canonical_form_map.end()) {
        if (verbose)
            std::cerr << "Replacing \"" << bible_book_candidate << "\" with \""
                      << non_canonical_form_and_canonical_form->second << "\".\n";
        return non_canonical_form_and_canonical_form->second;
    }

    return bible_book_candidate;
}

std::string MapBibleBookToCode(const bool verbose, const std::string &bible_book_candidate,
			       const std::string &books_of_the_bible_to_code_map_filename)
{
    std::unordered_map<std::string, std::string> bible_books_to_codes_map;
    MapIO::DeserialiseMap(books_of_the_bible_to_code_map_filename, &bible_books_to_codes_map);
    const auto bible_book_and_code(bible_books_to_codes_map.find(bible_book_candidate));
    if (bible_book_and_code == bible_books_to_codes_map.end()) {
        if (verbose)
            std::cerr << "No mapping from \"" << bible_book_candidate << "\" to a book code was found!\n";

	std::exit(EXIT_FAILURE); // Unknown bible book!
    }

    return bible_book_and_code->second;
}

void HandlePericopes(const bool verbose, const bool generate_solr_query, const std::string &bible_reference_candidate,
		     const std::string &pericopes_to_codes_map_filename)
{
    std::unordered_multimap<std::string, std::string> pericopes_to_codes_map;
    MapIO::DeserialiseMap(pericopes_to_codes_map_filename, &pericopes_to_codes_map);

    const auto begin_end(pericopes_to_codes_map.equal_range(bible_reference_candidate));
    if (begin_end.first != begin_end.second) {
        if (verbose)
            std::cerr << "Found a pericope to codes mapping.\n";
        std::string query;
        for (auto pair(begin_end.first); pair != begin_end.second; ++pair) {
            if (generate_solr_query) {
                if (not query.empty())
                    query += ' ';
                query += pair->first + "_" + pair->second;
            } else
                std::cout << pair->second << '\n';
        }
        if (generate_solr_query)
            std::cout << query << '\n';

	std::exit(EXIT_SUCCESS);
    }
}

void HandleBookRanges(const bool verbose, const bool generate_solr_query,
		      const std::string &books_of_the_bible_to_canonical_form_map_filename,
		      const std::string &books_of_the_bible_to_code_map_filename,
		      const std::string &bible_reference_candidate)
{
    const RegexMatcher *matcher(RegexMatcher::RegexMatcherFactory("([12])-([23])\\s*([A-Za-z]+)"));
    if (not matcher->matched(bible_reference_candidate)) {
	if (bible_reference_candidate.find('-') != std::string::npos) {
	    if (verbose)
		std::cerr << "Bad bible book range or random junk: " << bible_reference_candidate << '\n';
	    std::exit(EXIT_FAILURE);
	}
	return;
    }

    unsigned starting_volume;
    if (not StringUtil::ToUnsigned((*matcher)[1], &starting_volume) or starting_volume > 2)
	Error("\"" + (*matcher)[1] + "\" is not a valid starting volume!");

    unsigned ending_volume;
    if (not StringUtil::ToUnsigned((*matcher)[2], &ending_volume) or ending_volume > 3 or ending_volume <= starting_volume)
	Error("\"" + (*matcher)[2] + "\" is not a valid ending volume!");

    const std::string bible_book_candidate(CanoniseBibleBook(verbose, books_of_the_bible_to_canonical_form_map_filename,
							     (*matcher)[3]));
    if (verbose) {
	std::cout << "Identified a bible book range.  Starting volume " << starting_volume << ", ending volume "
		  << ending_volume << ", book is \"" << bible_book_candidate << "\".\n";
    }

    const std::string first_book_code(MapBibleBookToCode(verbose, std::to_string(starting_volume) + bible_book_candidate,
							 books_of_the_bible_to_code_map_filename));
    const std::string second_book_code(MapBibleBookToCode(verbose, std::to_string(ending_volume) + bible_book_candidate,
							  books_of_the_bible_to_code_map_filename));

    if (generate_solr_query) {
            std::cout << (first_book_code + "00000") << '_' << (first_book_code + "99999") << '\n';
            std::cout << (second_book_code + "00000") << '_' << (second_book_code + "99999") << '\n';
    }

    std::exit(EXIT_SUCCESS);
}

void HandleOrdinaryReferences(const bool verbose, const bool generate_solr_query, std::string bible_reference_candidate,
			      const std::string &bible_books_to_codes_map_filename,
			      const std::string &books_of_the_bible_to_canonical_form_map_filename)
{
    bible_reference_candidate = CanoniseLeadingNumber(InsertSpaceAtFirstLetterDigitBoundary(
                                    StringUtil::RemoveChars(" \t", &bible_reference_candidate)));
    std::string book_candidate, chapters_and_verses_candidate;
    SplitIntoBookAndChaptersAndVerses(bible_reference_candidate, &book_candidate, &chapters_and_verses_candidate);
    if (verbose) {
        std::cerr << "book_candidate = \"" << book_candidate << "\"\n";
        std::cerr << "chapters_and_verses_candidate = \"" << chapters_and_verses_candidate << "\"\n";
    }

    book_candidate = CanoniseBibleBook(verbose, books_of_the_bible_to_canonical_form_map_filename, book_candidate);
    const std::string book_code(MapBibleBookToCode(verbose, book_candidate, bible_books_to_codes_map_filename));
    if (verbose)
        std::cerr << "book code = \"" << book_code << "\"\n";
    if (chapters_and_verses_candidate.empty()) {
        if (generate_solr_query)
            std::cout << (book_code + "00000") << '_' << (book_code + "99999") << '\n';
        else
            std::cout << book_code << "00000:" << book_code << "99999" << '\n';

	std::exit(EXIT_SUCCESS);
    }

    std::set<std::pair<std::string, std::string>> start_end;
    if (not ParseBibleReference(chapters_and_verses_candidate, book_code, &start_end)) {
        if (verbose)
            std::cerr << "The parsing of \"" << chapters_and_verses_candidate
                      << "\" as chapters and verses failed!\n";
	std::exit(EXIT_FAILURE);
    }

    std::string query;
    for (const auto &pair : start_end) {
        if (generate_solr_query) {
            if (not query.empty())
                query += ' ';
            query += pair.first + "_" + pair.second;
        } else
            std::cout << pair.first << ':' << pair.second << '\n';
    }
    if (generate_solr_query)
        std::cout << query << '\n';
}

static void Usage() __attribute__((noreturn));

static void Usage() {
    std::cerr << "usage: " << progname << " [--debug|--query] bible_reference_candidate\n";
    std::cerr << "          books_of_the_bible_to_code_map\n";
    std::cerr << "          books_of_the_bible_to_canonical_form_map pericopes_to_codes_map\n";
    std::cerr << '\n';
    std::cerr << "          When --debug has been specified additional tracing output will be generated.\n";
    std::cerr << "          When --query has been specified SOLR search queries will be output.\n";
    std::exit(EXIT_FAILURE);
}

int main(int argc, char **argv) {
    progname = argv[0];

    bool verbose(false), generate_solr_query(false);

    if (argc == 6) {
        if (std::strcmp(argv[1], "--debug") == 0)
            verbose = true;
        else if (std::strcmp(argv[1], "--query") == 0)
            generate_solr_query = true;
        else
            Usage();
        ++argv, --argc;
    }

    if (argc != 5)
        Usage();

    const std::string books_of_the_bible_to_code_map_filename(argv[2]);
    const std::string books_of_the_bible_to_canonical_form_map_filename(argv[3]);
    std::string bible_reference_candidate(StringUtil::Trim(StringUtil::ToLower(argv[1])));
    StringUtil::CollapseWhitespace(&bible_reference_candidate);

    HandlePericopes(verbose, generate_solr_query, bible_reference_candidate, argv[4]);
    HandleBookRanges(verbose, generate_solr_query, books_of_the_bible_to_canonical_form_map_filename,
		     books_of_the_bible_to_code_map_filename, bible_reference_candidate);
    HandleOrdinaryReferences(verbose, generate_solr_query, bible_reference_candidate,
			     books_of_the_bible_to_code_map_filename,
			     books_of_the_bible_to_canonical_form_map_filename);
}
<|endoftext|>


<commit_before><commit_msg>Remove<commit_after><|endoftext|>


<commit_before>/*
 * (C) 2014 Kimmo Lindholm <kimmo.lindholm@gmail.com> Kimmoli
 *
 * Routines for TCA8424
 *
 *
 *
 *
 */

#include <linux/i2c-dev.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <linux/input.h>
#include "tca8424.h"

int tca8424_reset(int file)
{
    const unsigned char buf[4] = {0x00, 0x06, 0x00, 0x01};

    if (write(file, buf, 4) != 4)
    {
        close(file);
        return -3;
    }
    return file;
}

int tca8424_leds(int file, unsigned char leds)
{
    unsigned char buf[9] = {0x00, 0x06, 0x20, 0x03, 0x00, 0x07, 0x01, 0x00, leds};

    if (write(file, buf, 9) != 9)
    {
        close(file);
        return -4;
    }
    return file;
}

int tca8424_initComms(unsigned char addr)
{
    int file;

    /* open file and start ioctl */
    if ((file = open( "/dev/i2c-1", O_RDWR )) < 0)
    {
        return -1;
    }
    if (ioctl( file, I2C_SLAVE, addr) < 0)
    {
        close(file);
        return -2;
    }
    return file;
}

int tca8424_closeComms(int file)
{
    close(file);
    return file;
}

int tca8424_readInputReport(int file, char* report)
{
    const unsigned char buf[6] = {0x00, 0x06, 0x11, 0x02, 0x00, 0x07};

    if (write(file, buf, 6) != 6)
    {
        close(file);
        return -5;
    }

    memset(report, 0, 12);
    if (read(file, report, 11) != 11)
    {
        close(file);
        return -6;
    }

    return file;
}

int tca8424_readMemory(int file, int start, int len, char* data)
{
    unsigned char buf[2] = {start & 0xff, (start>>8) & 0xff};

    if (write(file, buf, 2) != 2)
    {
        close(file);
        return -11;
    }

    if (read(file, data, len) != len)
    {
        close(file);
        return -12;
    }

    return file;
}

/*
 *
 * dat Horrible key-press decoder
 *
 */

const char* tca8424_processKeyMap(char *input, int *c, int *shift, int *alt, int *ctrl)
{
    unsigned char k = input[5];

    *c = 0;
    *shift = false;
    *alt = false;
    *ctrl = false;

    /* first check for shift, alt and ctrl */
    if (k == 0x9E || k == 0xBC)
    {
        *shift = true;
    }
    else if (k == 0xAE || k == 0xBE)
    {
        *alt = true;
    }
    else if (k == 0xB3)
    {
        *ctrl = true;
        return "! Ctrl";
    }

    /* if alt, use alternate key mapping */
    if (*alt)
    {
        k = input[6];
        if (k == 0xC1) { *c = KEY_TAB; return "A Tab"; }
        if (k == 0xF1) { *c = KEY_1; return "Q 1"; }
        if (k == 0xA2) { *c = KEY_COMMA; *shift = true; return "Z <"; }
        if (k == 0xC2) { *c = KEY_1; *shift = true; return "S !"; }
        if (k == 0xF2) { *c = KEY_2; return "W 2"; }
        if (k == 0xA3) { *c = KEY_DOT; *shift = true; return "X >"; }
        if (k == 0xC3) { *c = KEY_3; *shift = true; return "D #"; }
        if (k == 0xF3) { *c = KEY_3; return "E 3"; }
        if (k == 0xA4) { *c = KEY_MINUS; *shift = true; return "C _"; }
        if (k == 0xC4) { *c = KEY_4; *shift = true; return "F $"; }
        if (k == 0xF4) { *c = KEY_4; return "R 4"; }
        if (k == 0xA5) { *c = KEY_MINUS; return "V -"; }
        if (k == 0xC5) { *c = KEY_5; *shift = true; return "G %"; }
        if (k == 0xF5) { *c = KEY_5; return "T 5"; }
        if (k == 0xA6) { *c = KEY_KPPLUS; return "B +"; }
        if (k == 0xC6) { *c = KEY_EQUAL; return "H ="; }
        if (k == 0xF6) { *c = KEY_6; return "Y 6"; }
        if (k == 0xA7) { *c = KEY_APOSTROPHE; *shift = true; return "N """; }
        if (k == 0xC7) { *c = KEY_7; *shift = true; return "J &"; }
        if (k == 0xF7) { *c = KEY_7; return "U 7"; }
        if (k == 0xA8) { *c = KEY_APOSTROPHE; return "M '"; }
        if (k == 0xC8) { *c = KEY_8; *shift = true; return "K *"; }
        if (k == 0xF8) { *c = KEY_8; return "I 8"; }
        if (k == 0xC9) { *c = KEY_9; *shift = true; return "L ("; }
        if (k == 0xF9) { *c = KEY_9; return "O 9"; }
        if (k == 0xAA) { *c = KEY_SEMICOLON; *shift = true; return ". :"; }
        if (k == 0xA9) { *c = KEY_SEMICOLON; return ", ;"; }
        if (k == 0xCA) { *c = KEY_0; *shift = true; return "? )"; }
        if (k == 0xFA) { *c = KEY_0; return "P 0"; }
        if (k == 0xB4) { *c = KEY_GRAVE; *shift = true; return "@ ~"; }
        if (k == 0xB8) { *c = KEY_6; *shift = true; return "/ ^"; }
        if (k == 0xFD) { *c = KEY_HOME; return "Left Arrow"; }
        if (k == 0x9D) { *c = KEY_END; return "Right Arrow"; }
        if (k == 0xFC) { *c = KEY_PAGEUP; return "Up arrow"; }
        if (k == 0xBD) { *c = KEY_PAGEDOWN; return "Down arrow"; }
        if (k == 0xB9) { *c = KEY_ESC; return "| Escape"; }

        if (k == 0x00) return "! Released";

        return "* Unknown";
    }

    /* if shift, check the next key in map */
    if (*shift)
        k = input[6];

    if (k == 0xC1) { *c = KEY_A; return "A Tab"; }
    if (k == 0xF1) { *c = KEY_Q; return "Q 1"; }
    if (k == 0xA2) { *c = KEY_Z; return "Z <"; }
    if (k == 0xC2) { *c = KEY_S; return "S !"; }
    if (k == 0xF2) { *c = KEY_W; return "W 2"; }
    if (k == 0xA3) { *c = KEY_X; return "X >"; }
    if (k == 0xC3) { *c = KEY_D; return "D #"; }
    if (k == 0xF3) { *c = KEY_E; return "E 3"; }
    if (k == 0xA4) { *c = KEY_C; return "C _"; }
    if (k == 0xB4) { *c = KEY_2; *shift = true; return "@ ~"; }
    if (k == 0xC4) { *c = KEY_F; return "F $"; }
    if (k == 0xF4) { *c = KEY_R; return "R 4"; }
    if (k == 0xA5) { *c = KEY_V; return "V -"; }
    if (k == 0xB5) { *c = KEY_SPACE; return "Space1"; }
    if (k == 0xC5) { *c = KEY_G; return "G %"; }
    if (k == 0xF5) { *c = KEY_T; return "T 5"; }
    if (k == 0xA6) { *c = KEY_B; return "B +"; }
    if (k == 0xB6) { *c = KEY_SPACE; return "Space2"; }
    if (k == 0xC6) { *c = KEY_H; return "H ="; }
    if (k == 0xF6) { *c = KEY_Y; return "Y 6"; }
    if (k == 0xA7) { *c = KEY_N; return "N """; }
    if (k == 0xB7) { *c = KEY_SPACE; return "Space3 Sym"; }
    if (k == 0xC7) { *c = KEY_J; return "J &"; }
    if (k == 0xF7) { *c = KEY_U; return "U 7"; }
    if (k == 0xA8) { *c = KEY_M; return "M '"; }
    if (k == 0xB8) { *c = KEY_SLASH; return "/ ^"; }
    if (k == 0xC8) { *c = KEY_K; return "K *"; }
    if (k == 0xF8) { *c = KEY_I; return "I 8"; }
    if (k == 0xA9) { *c = KEY_COMMA; return ", ;"; }
    if (k == 0xC9) { *c = KEY_L; return "L ("; }
    if (k == 0xF9) { *c = KEY_O; return "O 9"; }
    if (k == 0xAA) { *c = KEY_DOT; return ". :"; }
    if (k == 0xCA) { *c = KEY_SLASH; *shift = true; return "? )"; }
    if (k == 0xFA) { *c = KEY_P; return "P 0"; }
    if (k == 0xCB) { *c = KEY_ENTER; return "Return"; }
    if (k == 0xFB) { *c = KEY_BACKSPACE; return "Del"; }
    if (k == 0xFC) { *c = KEY_UP; return "Up arrow"; }
    if (k == 0x9C) { *c = KEY_ENTER; return "OK"; }
    if (k == 0xBD) { *c = KEY_DOWN; return "Down arrow"; }
    if (k == 0xFD) { *c = KEY_LEFT; return "Left Arrow"; }
    if (k == 0x9D) { *c = KEY_RIGHT; return "Right Arrow"; }
    if (k == 0xB9) { *c = KEY_BACKSLASH; return "| Escape"; }

    if (k == 0x00) return "! Released";

    return "* Unknown";
}
<commit_msg>Fix for PageUp/PageDown<commit_after>/*
 * (C) 2014 Kimmo Lindholm <kimmo.lindholm@gmail.com> Kimmoli
 *
 * Routines for TCA8424
 *
 *
 *
 *
 */

#include <linux/i2c-dev.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <linux/input.h>
#include "tca8424.h"

int tca8424_reset(int file)
{
    const unsigned char buf[4] = {0x00, 0x06, 0x00, 0x01};

    if (write(file, buf, 4) != 4)
    {
        close(file);
        return -3;
    }
    return file;
}

int tca8424_leds(int file, unsigned char leds)
{
    unsigned char buf[9] = {0x00, 0x06, 0x20, 0x03, 0x00, 0x07, 0x01, 0x00, leds};

    if (write(file, buf, 9) != 9)
    {
        close(file);
        return -4;
    }
    return file;
}

int tca8424_initComms(unsigned char addr)
{
    int file;

    /* open file and start ioctl */
    if ((file = open( "/dev/i2c-1", O_RDWR )) < 0)
    {
        return -1;
    }
    if (ioctl( file, I2C_SLAVE, addr) < 0)
    {
        close(file);
        return -2;
    }
    return file;
}

int tca8424_closeComms(int file)
{
    close(file);
    return file;
}

int tca8424_readInputReport(int file, char* report)
{
    const unsigned char buf[6] = {0x00, 0x06, 0x11, 0x02, 0x00, 0x07};

    if (write(file, buf, 6) != 6)
    {
        close(file);
        return -5;
    }

    memset(report, 0, 12);
    if (read(file, report, 11) != 11)
    {
        close(file);
        return -6;
    }

    return file;
}

int tca8424_readMemory(int file, int start, int len, char* data)
{
    unsigned char buf[2] = {start & 0xff, (start>>8) & 0xff};

    if (write(file, buf, 2) != 2)
    {
        close(file);
        return -11;
    }

    if (read(file, data, len) != len)
    {
        close(file);
        return -12;
    }

    return file;
}

/*
 *
 * dat Horrible key-press decoder
 *
 */

const char* tca8424_processKeyMap(char *input, int *c, int *shift, int *alt, int *ctrl)
{
    unsigned char k = input[5];

    *c = 0;
    *shift = false;
    *alt = false;
    *ctrl = false;

    /* first check for shift, alt and ctrl */
    if (k == 0x9E || k == 0xBC)
    {
        *shift = true;
    }
    else if (k == 0xAE || k == 0xBE)
    {
        *alt = true;
    }
    else if (k == 0xB3)
    {
        *ctrl = true;
        return "! Ctrl";
    }

    /* if alt, use alternate key mapping */
    if (*alt)
    {
        k = input[6];
        if (k == 0xC1) { *c = KEY_TAB; return "A Tab"; }
        if (k == 0xF1) { *c = KEY_1; return "Q 1"; }
        if (k == 0xA2) { *c = KEY_COMMA; *shift = true; return "Z <"; }
        if (k == 0xC2) { *c = KEY_1; *shift = true; return "S !"; }
        if (k == 0xF2) { *c = KEY_2; return "W 2"; }
        if (k == 0xA3) { *c = KEY_DOT; *shift = true; return "X >"; }
        if (k == 0xC3) { *c = KEY_3; *shift = true; return "D #"; }
        if (k == 0xF3) { *c = KEY_3; return "E 3"; }
        if (k == 0xA4) { *c = KEY_MINUS; *shift = true; return "C _"; }
        if (k == 0xC4) { *c = KEY_4; *shift = true; return "F $"; }
        if (k == 0xF4) { *c = KEY_4; return "R 4"; }
        if (k == 0xA5) { *c = KEY_MINUS; return "V -"; }
        if (k == 0xC5) { *c = KEY_5; *shift = true; return "G %"; }
        if (k == 0xF5) { *c = KEY_5; return "T 5"; }
        if (k == 0xA6) { *c = KEY_KPPLUS; return "B +"; }
        if (k == 0xC6) { *c = KEY_EQUAL; return "H ="; }
        if (k == 0xF6) { *c = KEY_6; return "Y 6"; }
        if (k == 0xA7) { *c = KEY_APOSTROPHE; *shift = true; return "N """; }
        if (k == 0xC7) { *c = KEY_7; *shift = true; return "J &"; }
        if (k == 0xF7) { *c = KEY_7; return "U 7"; }
        if (k == 0xA8) { *c = KEY_APOSTROPHE; return "M '"; }
        if (k == 0xC8) { *c = KEY_8; *shift = true; return "K *"; }
        if (k == 0xF8) { *c = KEY_8; return "I 8"; }
        if (k == 0xC9) { *c = KEY_9; *shift = true; return "L ("; }
        if (k == 0xF9) { *c = KEY_9; return "O 9"; }
        if (k == 0xAA) { *c = KEY_SEMICOLON; *shift = true; return ". :"; }
        if (k == 0xA9) { *c = KEY_SEMICOLON; return ", ;"; }
        if (k == 0xCA) { *c = KEY_0; *shift = true; return "? )"; }
        if (k == 0xFA) { *c = KEY_0; return "P 0"; }
        if (k == 0xB4) { *c = KEY_GRAVE; *shift = true; return "@ ~"; }
        if (k == 0xB8) { *c = KEY_6; *shift = true; return "/ ^"; }
        if (k == 0xFD) { *c = KEY_HOME; return "Left Arrow"; }
        if (k == 0x9D) { *c = KEY_END; return "Right Arrow"; }
        if (k == 0xFC) { *c = KEY_PAGEUP; *shift = true; return "Up arrow"; }
        if (k == 0xBD) { *c = KEY_PAGEDOWN; *shift = true; return "Down arrow"; }
        if (k == 0xB9) { *c = KEY_ESC; return "| Escape"; }

        if (k == 0x00) return "! Released";

        return "* Unknown";
    }

    /* if shift, check the next key in map */
    if (*shift)
        k = input[6];

    if (k == 0xC1) { *c = KEY_A; return "A Tab"; }
    if (k == 0xF1) { *c = KEY_Q; return "Q 1"; }
    if (k == 0xA2) { *c = KEY_Z; return "Z <"; }
    if (k == 0xC2) { *c = KEY_S; return "S !"; }
    if (k == 0xF2) { *c = KEY_W; return "W 2"; }
    if (k == 0xA3) { *c = KEY_X; return "X >"; }
    if (k == 0xC3) { *c = KEY_D; return "D #"; }
    if (k == 0xF3) { *c = KEY_E; return "E 3"; }
    if (k == 0xA4) { *c = KEY_C; return "C _"; }
    if (k == 0xB4) { *c = KEY_2; *shift = true; return "@ ~"; }
    if (k == 0xC4) { *c = KEY_F; return "F $"; }
    if (k == 0xF4) { *c = KEY_R; return "R 4"; }
    if (k == 0xA5) { *c = KEY_V; return "V -"; }
    if (k == 0xB5) { *c = KEY_SPACE; return "Space1"; }
    if (k == 0xC5) { *c = KEY_G; return "G %"; }
    if (k == 0xF5) { *c = KEY_T; return "T 5"; }
    if (k == 0xA6) { *c = KEY_B; return "B +"; }
    if (k == 0xB6) { *c = KEY_SPACE; return "Space2"; }
    if (k == 0xC6) { *c = KEY_H; return "H ="; }
    if (k == 0xF6) { *c = KEY_Y; return "Y 6"; }
    if (k == 0xA7) { *c = KEY_N; return "N """; }
    if (k == 0xB7) { *c = KEY_SPACE; return "Space3 Sym"; }
    if (k == 0xC7) { *c = KEY_J; return "J &"; }
    if (k == 0xF7) { *c = KEY_U; return "U 7"; }
    if (k == 0xA8) { *c = KEY_M; return "M '"; }
    if (k == 0xB8) { *c = KEY_SLASH; return "/ ^"; }
    if (k == 0xC8) { *c = KEY_K; return "K *"; }
    if (k == 0xF8) { *c = KEY_I; return "I 8"; }
    if (k == 0xA9) { *c = KEY_COMMA; return ", ;"; }
    if (k == 0xC9) { *c = KEY_L; return "L ("; }
    if (k == 0xF9) { *c = KEY_O; return "O 9"; }
    if (k == 0xAA) { *c = KEY_DOT; return ". :"; }
    if (k == 0xCA) { *c = KEY_SLASH; *shift = true; return "? )"; }
    if (k == 0xFA) { *c = KEY_P; return "P 0"; }
    if (k == 0xCB) { *c = KEY_ENTER; return "Return"; }
    if (k == 0xFB) { *c = KEY_BACKSPACE; return "Del"; }
    if (k == 0xFC) { *c = KEY_UP; return "Up arrow"; }
    if (k == 0x9C) { *c = KEY_ENTER; return "OK"; }
    if (k == 0xBD) { *c = KEY_DOWN; return "Down arrow"; }
    if (k == 0xFD) { *c = KEY_LEFT; return "Left Arrow"; }
    if (k == 0x9D) { *c = KEY_RIGHT; return "Right Arrow"; }
    if (k == 0xB9) { *c = KEY_BACKSLASH; return "| Escape"; }

    if (k == 0x00) return "! Released";

    return "* Unknown";
}
<|endoftext|>


<commit_before>//**************************************************************************************************
//
//     OSSIM Open Source Geospatial Data Processing Library
//     See top level LICENSE.txt file for license information
//
//**************************************************************************************************
#include "ossimCsm3Loader.h"
#include "ossimCsm3SensorModel.h"
#include <ossim/plugin/ossimDynamicLibrary.h>
#include <ossim/base/ossimPreferences.h>
#include <ossim/base/ossimDirectory.h>
#include <ossim/base/ossimNotify.h>
#include <csm/Plugin.h>
#include <csm/NitfIsd.h>
#include "VTSMisc.h"

#if OSSIM_HAS_MSP
#include <SensorModel/SensorModelService.h>
#endif

#ifdef _WIN32
#include <windows.h>
# include <io.h>
#else
# include <cstdio>  // for sprintf
# include <cstring> // for strstr
# include <dirent.h>
# include <dlfcn.h> // for dlopen, dlclose
# include <errno.h> // for errno
#endif

using namespace csm;
using namespace std;

#ifdef _WIN32
typedef HINSTANCE DllHandle;
static const string dylibExt = ".dll";
#else
typedef void* DllHandle;
static const string dylibExt = ".so";
#endif

ossimCsm3Loader::ossimCsm3Loader()
{
   static const char* MODULE = "ossimCsm3Loader Constructor -- ";

#if OSSIM_HAS_MSP
   try
   {
      //cout<<"In ossimCsm3Loader Ctor"<<endl;//#### TODO REMOVE
      MSP::SMS::SensorModelService sms;
      MSP::SMS::NameList pluginList;
      sms.getAllRegisteredPlugins(pluginList);
   }
   catch(exception &mspError)
   {
      cout<<"Exception: "<<mspError.what()<<endl;;
   }

#else
   // get plugin path from the preferences file and verify it
   ossimFilename pluginPath (ossimPreferences::instance()->findPreference("csm3_plugin_path"));
   if(pluginPath.empty())
   {
      ossimNotify(ossimNotifyLevel_WARN)<<MODULE<<"No CSM plugin path was specified. Make sure that"
            " the ossim preferences file contains \"csm3_plugin_path\" entry."<<endl;
      return;
   }

   // Load all of the dynamic libraries in the plugin path
   // first get the list of all the dynamic libraries found
   std::vector<ossimFilename> dllfiles;
   ossimDirectory pluginDir(pluginPath);
   pluginDir.findAllFilesThatMatch(dllfiles, dylibExt );

   for (int i=0; i<dllfiles.size(); i++)
   {
      // when loaded, each dynamic libraries found will register itself in the Plugin object
      // the list is accessible using  PluginList pluginList = Plugin::getList( )

      ossimDynamicLibrary *lib = new ossimDynamicLibrary;
      if (!lib->load(dllfiles[i]))
      {
         ossimNotify(ossimNotifyLevel_WARN)
         << "loadPlugins: " + dllfiles[i] + "\" file failed to load." << std::endl;
      }
   }
#endif
   return;
}

void ossimCsm3Loader::getAvailablePluginNames(vector<string>& plugins)
{
   plugins.clear();

#if OSSIM_HAS_MSP
   MSP::SMS::NameList pluginList;
   try
   {
      MSP::SMS::SensorModelService sms;
      sms.getAllRegisteredPlugins(pluginList);
   }
   catch(exception &mspError)
   {
      cout<<"Exception: "<<mspError.what()<<endl;;
   }

   MSP::SMS::NameList::iterator plugin = pluginList.begin();
   while (plugin != pluginList.end())
   {
      plugins.push_back(*plugin);
      ++plugin;
   }
#else

   // now get the PluginList to get the PluginName
   PluginList pluginList = Plugin::getList( );
   for( PluginList::const_iterator i = pluginList.begin(); i != pluginList.end(); i++ )
      plugins.push_back( (*i)->getPluginName() );
#endif
}

void ossimCsm3Loader::getAvailableSensorModelNames(const string& pluginName,
                                                   vector<std::string>& models)
{
   models.clear();

#if OSSIM_HAS_MSP
   MSP::SMS::NameList modelList;
   try
   {
      MSP::SMS::SensorModelService sms;
      sms.listModels(pluginName, modelList);
   }
   catch(exception &mspError)
   {
      cout<<"Exception: "<<mspError.what()<<endl;;
   }

   MSP::SMS::NameList::iterator model = modelList.begin();
   while (model != modelList.end())
   {
      models.push_back(*model);
      ++model;
   }
#else

   // now get the PluginList to get the PluginName
   PluginList pluginList = Plugin::getList( );
   for( PluginList::const_iterator i = pluginList.begin(); i != pluginList.end(); i++ )
   {
      if( (*i)->getPluginName() != string(pluginName) )
         continue;

      for( size_t j = 0; j < (*i)->getNumModels(); j++ )
         models.push_back( (*i)->getModelName( j ) );
   }
#endif

   if (models.empty())
   {
      ossimNotify(ossimNotifyLevel_WARN)
                                << "getAvailableSensorModelNames: No plugins were found with the name \"" + pluginName + "\""
                                << endl;
   }
}

RasterGM* ossimCsm3Loader::loadModelFromState(const string& pPluginName,
                                              const string& pSensorModelName,
                                              const string& pSensorState )
{
   static const char* MODULE = "ossimCsm3Loader::loadModelFromState() -- ";
   Model* sensorModel = 0;
   RasterGM* rgm = 0;

   // Make sure the input data is not NULL. For MSP, the plugin name and model name are not used:
   if( pSensorState.empty() )
   {
      ossimNotify(ossimNotifyLevel_WARN)<<MODULE<<"Sensor state is empty." << std::endl;
      return NULL;
   }

   try
   {

#if OSSIM_HAS_MSP
      MSP::SMS::SensorModelService sms;
      sensorModel = sms.createModelFromState(pSensorState.c_str());
#else
      // Make sure the input data is not NULL
      if( pPluginName.empty() || pSensorModelName.empty())
      {
         ossimNotify(ossimNotifyLevel_WARN)<<MODULE<<"Plugin Name and"
               " Sensor Model Name must be specified." << endl;
         return NULL;
      }
      const Plugin* plugin = Plugin::findPlugin( pPluginName );
      if( plugin == NULL )
      {
         ossimNotify(ossimNotifyLevel_WARN)<<MODULE<<"No plugin "
               " with the name \"" << pPluginName << "\" was found." << endl;
         return NULL;
      }

      // Load the sensor model using the appropriate information
      bool constructible = false;

      // See if it's possible to construct the sensor model from the state
      constructible = plugin->canModelBeConstructedFromState(pSensorModelName, pSensorState);
      if(plugin->canModelBeConstructedFromState(pSensorModelName, pSensorState))
      {
         plugin->canModelBeConstructedFromState(pSensorModelName, pSensorState);
      }
      else
      {
         ossimNotify(ossimNotifyLevel_WARN)<<MODULE<<"The specified state cannot be "
               "used to construct a sensor model."<< endl;
         return NULL;
      }

      // Create the sensor model from the plugin and sensor state
      sensorModel = plugin->constructModelFromState( pSensorState );
#endif

      if(sensorModel)
      {
         rgm = dynamic_cast<RasterGM*>(sensorModel);
      }
      else
      {
         ossimNotify(ossimNotifyLevel_WARN)<<MODULE<<"Failed to create sensor model "
               "from sensor state."<< endl;
      }

   }
   catch(exception &e)
   {
      ossimNotify(ossimNotifyLevel_WARN)<<MODULE<<"Hit exception: "<<e.what()<<endl;
   }

   return rgm;
}

RasterGM* ossimCsm3Loader::loadModelFromFile(const string& pPluginName,
                                             const string& pSensorModelName,
                                             const string& pInputImage,
                                             ossim_uint32 index )
{
   static const char* MODULE = "ossimCsm3Loader::loadModelFromFile() -- ";
   Model* sensorModel = NULL;
   RasterGM* rgm = 0;

   // Make sure the input data is not NULL. For MSP, the plugin name is not used:
   if( pSensorModelName.empty() || pInputImage.empty())
   {
      ossimNotify(ossimNotifyLevel_WARN)<<MODULE<<"Sensor model name and/or image filename is "
            "empty." << std::endl;
      return NULL;
   }

   do {
      try {

#if OSSIM_HAS_MSP
         MSP::SMS::SensorModelService sms;
         const char* modelName = 0;
         if (pSensorModelName.size())
            modelName = pSensorModelName.c_str();
         MSP::ImageIdentifier entry ("IMAGE_INDEX", ossimString::toString(index).string());
         sms.setPluginPreferencesRigorousBeforeRpc();
         sensorModel = sms.createModelFromFile(pInputImage.c_str(), modelName, &entry);
#else

         // Make sure the input data is not NULL
         if( pPluginName.empty())
         {
            ossimNotify(ossimNotifyLevel_WARN)<<MODULE<<"Plugin Name must be specified."<< endl;
            return NULL;
         }

         const Plugin* plugin = Plugin::findPlugin( pPluginName );
         if( plugin == NULL )
         {
            ossimNotify(ossimNotifyLevel_WARN)<<MODULE<<"No plugin with the name \"" << pPluginName
                  << "\" was found."<< endl;
            return NULL;
         }

         // Load the sensor model using the appropriate information
         WarningList warnings;
         bool constructible = false;

         // First try to construct the sensor model from the filename ISD
         Isd* fnameIsd = new Isd( pInputImage );
         try
         {
            constructible = plugin->canModelBeConstructedFromISD( *fnameIsd,
                                                                  pSensorModelName, &warnings);
         }
         catch(...)
         {
            delete fnameIsd;
            constructible = false;
         }

         if (constructible)
         {
            //ossimNotify(ossimNotifyLevel_INFO)<<MODULE<< "Constructing sensor model via filename"<<endl;
            sensorModel = plugin->constructModelFromISD( *fnameIsd, pSensorModelName );
            delete fnameIsd;
            break;
         }

         // Next try a NITF 2.1 ISD
         Nitf21Isd* nitf21Isd = new Nitf21Isd( pInputImage );
         try
         {
            initNitf21ISD( nitf21Isd, pInputImage, index, &warnings );
            constructible = plugin->canModelBeConstructedFromISD( *nitf21Isd,
                                                                  pSensorModelName, &warnings);
         }
         catch(...)
         {
            delete nitf21Isd;
            constructible = false;
         }

         if (constructible)
         {
            //ossimNotify(ossimNotifyLevel_INFO) << "Constructing sensor model from NITF 2.1 file" << endl;
            sensorModel = plugin->constructModelFromISD( *nitf21Isd, pSensorModelName );
            delete nitf21Isd;
            break;
         }

         // finally try a NITF 2.0 ISD
         Nitf20Isd* nitf20Isd = new Nitf20Isd( pInputImage );

         try {
            initNitf20ISD( nitf20Isd, pInputImage, index, &warnings );
            constructible = plugin->canModelBeConstructedFromISD( *nitf20Isd,
                                                                  pSensorModelName, &warnings);
         }
         catch(...)
         {
            delete nitf20Isd;
            constructible = false;
         }

         if (constructible)
         {
            //ossimNotify(ossimNotifyLevel_INFO) << "Constructing sensor model from NITF 2.0 file" << endl;
            sensorModel = plugin->constructModelFromISD( *nitf20Isd, pSensorModelName );
            delete nitf20Isd;
            break;
         }
#endif

      }
      catch(exception& e)
      {
         // This is noisy. Leave out for production:
         // ossimNotify(ossimNotifyLevel_WARN)<< "Exception: "<< e.what() << endl;
      }
   } while (false);

   if( sensorModel )
      return dynamic_cast<RasterGM*>(sensorModel);

//   ossimNotify(ossimNotifyLevel_WARN)<<MODULE<<"Unable to create sensor model \""
//         << pSensorModelName<< "\" using the image \"" + pInputImage + "\""  << endl;
   return NULL;
}

ossimCsm3SensorModel* ossimCsm3Loader::getSensorModel(const ossimFilename& filename,
                                                      ossim_uint32 index)
{
   ostringstream xmsg;
   xmsg<<__FILE__<<": getCsmSensorModel() -- ";

   ossimCsm3SensorModel* model = 0;
   string pluginName = "";
   string sensorName = "";
   string fname = filename;

   csm::RasterGM* csmModel = 0;
   try
   {
#if OSSIM_HAS_MSP
      MSP::SMS::SensorModelService sms;
      const char* modelName = 0;
      MSP::ImageIdentifier entry ("IMAGE_INDEX", ossimString::toString(index).string());
      sms.setPluginPreferencesRigorousBeforeRpc();
      csm::Model* base = sms.createModelFromFile(filename.c_str(), modelName, &entry);
      csmModel = dynamic_cast<csm::RasterGM*>(base);
#else
      std::vector<string> pluginNames;
      getAvailablePluginNames(pluginNames);
      for(int i = 0; i < pluginNames.size(); ++i)
      {
         std::vector<string> sensorModelNames;
         getAvailableSensorModelNames( pluginNames[i], sensorModelNames );
         for(int j = 0; j<sensorModelNames.size() && !csmModel; ++j)
            csmModel = loadModelFromFile( pluginNames[i], sensorModelNames[j], filename, index);
      }
#endif
      if (csmModel)
      {
         clog<<"ossimCsm3Loader::getSensorModel()  modelName: "<<base->getModelName()<<endl;
         model = new ossimCsm3SensorModel(csmModel);
      }
   }
   catch (exception& e)
   {
      xmsg<<"Caught exception: "<<e.what();
      throw ossimException(xmsg.str());
   }
   return model;
}

<commit_msg>Fixed comile error<commit_after>//**************************************************************************************************
//
//     OSSIM Open Source Geospatial Data Processing Library
//     See top level LICENSE.txt file for license information
//
//**************************************************************************************************
#include "ossimCsm3Loader.h"
#include "ossimCsm3SensorModel.h"
#include <ossim/plugin/ossimDynamicLibrary.h>
#include <ossim/base/ossimPreferences.h>
#include <ossim/base/ossimDirectory.h>
#include <ossim/base/ossimNotify.h>
#include <csm/Plugin.h>
#include <csm/NitfIsd.h>
#include "VTSMisc.h"

#if OSSIM_HAS_MSP
#include <SensorModel/SensorModelService.h>
#endif

#ifdef _WIN32
#include <windows.h>
# include <io.h>
#else
# include <cstdio>  // for sprintf
# include <cstring> // for strstr
# include <dirent.h>
# include <dlfcn.h> // for dlopen, dlclose
# include <errno.h> // for errno
#endif

using namespace csm;
using namespace std;

#ifdef _WIN32
typedef HINSTANCE DllHandle;
static const string dylibExt = ".dll";
#else
typedef void* DllHandle;
static const string dylibExt = ".so";
#endif

ossimCsm3Loader::ossimCsm3Loader()
{
   static const char* MODULE = "ossimCsm3Loader Constructor -- ";

#if OSSIM_HAS_MSP
   try
   {
      //cout<<"In ossimCsm3Loader Ctor"<<endl;//#### TODO REMOVE
      MSP::SMS::SensorModelService sms;
      MSP::SMS::NameList pluginList;
      sms.getAllRegisteredPlugins(pluginList);
   }
   catch(exception &mspError)
   {
      cout<<"Exception: "<<mspError.what()<<endl;;
   }

#else
   // get plugin path from the preferences file and verify it
   ossimFilename pluginPath (ossimPreferences::instance()->findPreference("csm3_plugin_path"));
   if(pluginPath.empty())
   {
      ossimNotify(ossimNotifyLevel_WARN)<<MODULE<<"No CSM plugin path was specified. Make sure that"
            " the ossim preferences file contains \"csm3_plugin_path\" entry."<<endl;
      return;
   }

   // Load all of the dynamic libraries in the plugin path
   // first get the list of all the dynamic libraries found
   std::vector<ossimFilename> dllfiles;
   ossimDirectory pluginDir(pluginPath);
   pluginDir.findAllFilesThatMatch(dllfiles, dylibExt );

   for (int i=0; i<dllfiles.size(); i++)
   {
      // when loaded, each dynamic libraries found will register itself in the Plugin object
      // the list is accessible using  PluginList pluginList = Plugin::getList( )

      ossimDynamicLibrary *lib = new ossimDynamicLibrary;
      if (!lib->load(dllfiles[i]))
      {
         ossimNotify(ossimNotifyLevel_WARN)
         << "loadPlugins: " + dllfiles[i] + "\" file failed to load." << std::endl;
      }
   }
#endif
   return;
}

void ossimCsm3Loader::getAvailablePluginNames(vector<string>& plugins)
{
   plugins.clear();

#if OSSIM_HAS_MSP
   MSP::SMS::NameList pluginList;
   try
   {
      MSP::SMS::SensorModelService sms;
      sms.getAllRegisteredPlugins(pluginList);
   }
   catch(exception &mspError)
   {
      cout<<"Exception: "<<mspError.what()<<endl;;
   }

   MSP::SMS::NameList::iterator plugin = pluginList.begin();
   while (plugin != pluginList.end())
   {
      plugins.push_back(*plugin);
      ++plugin;
   }
#else

   // now get the PluginList to get the PluginName
   PluginList pluginList = Plugin::getList( );
   for( PluginList::const_iterator i = pluginList.begin(); i != pluginList.end(); i++ )
      plugins.push_back( (*i)->getPluginName() );
#endif
}

void ossimCsm3Loader::getAvailableSensorModelNames(const string& pluginName,
                                                   vector<std::string>& models)
{
   models.clear();

#if OSSIM_HAS_MSP
   MSP::SMS::NameList modelList;
   try
   {
      MSP::SMS::SensorModelService sms;
      sms.listModels(pluginName, modelList);
   }
   catch(exception &mspError)
   {
      cout<<"Exception: "<<mspError.what()<<endl;;
   }

   MSP::SMS::NameList::iterator model = modelList.begin();
   while (model != modelList.end())
   {
      models.push_back(*model);
      ++model;
   }
#else

   // now get the PluginList to get the PluginName
   PluginList pluginList = Plugin::getList( );
   for( PluginList::const_iterator i = pluginList.begin(); i != pluginList.end(); i++ )
   {
      if( (*i)->getPluginName() != string(pluginName) )
         continue;

      for( size_t j = 0; j < (*i)->getNumModels(); j++ )
         models.push_back( (*i)->getModelName( j ) );
   }
#endif

   if (models.empty())
   {
      ossimNotify(ossimNotifyLevel_WARN)
                                << "getAvailableSensorModelNames: No plugins were found with the name \"" + pluginName + "\""
                                << endl;
   }
}

RasterGM* ossimCsm3Loader::loadModelFromState(const string& pPluginName,
                                              const string& pSensorModelName,
                                              const string& pSensorState )
{
   static const char* MODULE = "ossimCsm3Loader::loadModelFromState() -- ";
   Model* sensorModel = 0;
   RasterGM* rgm = 0;

   // Make sure the input data is not NULL. For MSP, the plugin name and model name are not used:
   if( pSensorState.empty() )
   {
      ossimNotify(ossimNotifyLevel_WARN)<<MODULE<<"Sensor state is empty." << std::endl;
      return NULL;
   }

   try
   {

#if OSSIM_HAS_MSP
      MSP::SMS::SensorModelService sms;
      sensorModel = sms.createModelFromState(pSensorState.c_str());
#else
      // Make sure the input data is not NULL
      if( pPluginName.empty() || pSensorModelName.empty())
      {
         ossimNotify(ossimNotifyLevel_WARN)<<MODULE<<"Plugin Name and"
               " Sensor Model Name must be specified." << endl;
         return NULL;
      }
      const Plugin* plugin = Plugin::findPlugin( pPluginName );
      if( plugin == NULL )
      {
         ossimNotify(ossimNotifyLevel_WARN)<<MODULE<<"No plugin "
               " with the name \"" << pPluginName << "\" was found." << endl;
         return NULL;
      }

      // Load the sensor model using the appropriate information
      bool constructible = false;

      // See if it's possible to construct the sensor model from the state
      constructible = plugin->canModelBeConstructedFromState(pSensorModelName, pSensorState);
      if(plugin->canModelBeConstructedFromState(pSensorModelName, pSensorState))
      {
         plugin->canModelBeConstructedFromState(pSensorModelName, pSensorState);
      }
      else
      {
         ossimNotify(ossimNotifyLevel_WARN)<<MODULE<<"The specified state cannot be "
               "used to construct a sensor model."<< endl;
         return NULL;
      }

      // Create the sensor model from the plugin and sensor state
      sensorModel = plugin->constructModelFromState( pSensorState );
#endif

      if(sensorModel)
      {
         rgm = dynamic_cast<RasterGM*>(sensorModel);
      }
      else
      {
         ossimNotify(ossimNotifyLevel_WARN)<<MODULE<<"Failed to create sensor model "
               "from sensor state."<< endl;
      }

   }
   catch(exception &e)
   {
      ossimNotify(ossimNotifyLevel_WARN)<<MODULE<<"Hit exception: "<<e.what()<<endl;
   }

   return rgm;
}

RasterGM* ossimCsm3Loader::loadModelFromFile(const string& pPluginName,
                                             const string& pSensorModelName,
                                             const string& pInputImage,
                                             ossim_uint32 index )
{
   static const char* MODULE = "ossimCsm3Loader::loadModelFromFile() -- ";
   Model* sensorModel = NULL;
   RasterGM* rgm = 0;

   // Make sure the input data is not NULL. For MSP, the plugin name is not used:
   if( pSensorModelName.empty() || pInputImage.empty())
   {
      ossimNotify(ossimNotifyLevel_WARN)<<MODULE<<"Sensor model name and/or image filename is "
            "empty." << std::endl;
      return NULL;
   }

   do {
      try {

#if OSSIM_HAS_MSP
         MSP::SMS::SensorModelService sms;
         const char* modelName = 0;
         if (pSensorModelName.size())
            modelName = pSensorModelName.c_str();
         MSP::ImageIdentifier entry ("IMAGE_INDEX", ossimString::toString(index).string());
         sms.setPluginPreferencesRigorousBeforeRpc();
         sensorModel = sms.createModelFromFile(pInputImage.c_str(), modelName, &entry);
#else

         // Make sure the input data is not NULL
         if( pPluginName.empty())
         {
            ossimNotify(ossimNotifyLevel_WARN)<<MODULE<<"Plugin Name must be specified."<< endl;
            return NULL;
         }

         const Plugin* plugin = Plugin::findPlugin( pPluginName );
         if( plugin == NULL )
         {
            ossimNotify(ossimNotifyLevel_WARN)<<MODULE<<"No plugin with the name \"" << pPluginName
                  << "\" was found."<< endl;
            return NULL;
         }

         // Load the sensor model using the appropriate information
         WarningList warnings;
         bool constructible = false;

         // First try to construct the sensor model from the filename ISD
         Isd* fnameIsd = new Isd( pInputImage );
         try
         {
            constructible = plugin->canModelBeConstructedFromISD( *fnameIsd,
                                                                  pSensorModelName, &warnings);
         }
         catch(...)
         {
            delete fnameIsd;
            constructible = false;
         }

         if (constructible)
         {
            //ossimNotify(ossimNotifyLevel_INFO)<<MODULE<< "Constructing sensor model via filename"<<endl;
            sensorModel = plugin->constructModelFromISD( *fnameIsd, pSensorModelName );
            delete fnameIsd;
            break;
         }

         // Next try a NITF 2.1 ISD
         Nitf21Isd* nitf21Isd = new Nitf21Isd( pInputImage );
         try
         {
            initNitf21ISD( nitf21Isd, pInputImage, index, &warnings );
            constructible = plugin->canModelBeConstructedFromISD( *nitf21Isd,
                                                                  pSensorModelName, &warnings);
         }
         catch(...)
         {
            delete nitf21Isd;
            constructible = false;
         }

         if (constructible)
         {
            //ossimNotify(ossimNotifyLevel_INFO) << "Constructing sensor model from NITF 2.1 file" << endl;
            sensorModel = plugin->constructModelFromISD( *nitf21Isd, pSensorModelName );
            delete nitf21Isd;
            break;
         }

         // finally try a NITF 2.0 ISD
         Nitf20Isd* nitf20Isd = new Nitf20Isd( pInputImage );

         try {
            initNitf20ISD( nitf20Isd, pInputImage, index, &warnings );
            constructible = plugin->canModelBeConstructedFromISD( *nitf20Isd,
                                                                  pSensorModelName, &warnings);
         }
         catch(...)
         {
            delete nitf20Isd;
            constructible = false;
         }

         if (constructible)
         {
            //ossimNotify(ossimNotifyLevel_INFO) << "Constructing sensor model from NITF 2.0 file" << endl;
            sensorModel = plugin->constructModelFromISD( *nitf20Isd, pSensorModelName );
            delete nitf20Isd;
            break;
         }
#endif

      }
      catch(exception& e)
      {
         // This is noisy. Leave out for production:
         // ossimNotify(ossimNotifyLevel_WARN)<< "Exception: "<< e.what() << endl;
      }
   } while (false);

   if( sensorModel )
      return dynamic_cast<RasterGM*>(sensorModel);

//   ossimNotify(ossimNotifyLevel_WARN)<<MODULE<<"Unable to create sensor model \""
//         << pSensorModelName<< "\" using the image \"" + pInputImage + "\""  << endl;
   return NULL;
}

ossimCsm3SensorModel* ossimCsm3Loader::getSensorModel(const ossimFilename& filename,
                                                      ossim_uint32 index)
{
   ostringstream xmsg;
   xmsg<<__FILE__<<": getCsmSensorModel() -- ";

   ossimCsm3SensorModel* model = 0;
   string pluginName = "";
   string sensorName = "";
   string fname = filename;

   csm::RasterGM* csmModel = 0;
   try
   {
#if OSSIM_HAS_MSP
      MSP::SMS::SensorModelService sms;
      const char* modelName = 0;
      MSP::ImageIdentifier entry ("IMAGE_INDEX", ossimString::toString(index).string());
      sms.setPluginPreferencesRigorousBeforeRpc();
      csm::Model* base = sms.createModelFromFile(filename.c_str(), modelName, &entry);
      csmModel = dynamic_cast<csm::RasterGM*>(base);
#else
      std::vector<string> pluginNames;
      getAvailablePluginNames(pluginNames);
      for(int i = 0; i < pluginNames.size(); ++i)
      {
         std::vector<string> sensorModelNames;
         getAvailableSensorModelNames( pluginNames[i], sensorModelNames );
         for(int j = 0; j<sensorModelNames.size() && !csmModel; ++j)
            csmModel = loadModelFromFile( pluginNames[i], sensorModelNames[j], filename, index);
      }
#endif
      if (csmModel)
      {
         clog<<"ossimCsm3Loader::getSensorModel()  modelName: "<<csmModel->getModelName()<<endl;
         model = new ossimCsm3SensorModel(csmModel);
      }
   }
   catch (exception& e)
   {
      xmsg<<"Caught exception: "<<e.what();
      throw ossimException(xmsg.str());
   }
   return model;
}

<|endoftext|>


<commit_before>#include "FCStdAfx.h"
#include "HAL.h"
#include "RC_Comms.h"
#include "GS_Comms.h"
#include "utils/Clock.h"

#include <boost/asio.hpp>
#include <boost/thread.hpp>

#include <sys/time.h>
#include <sys/resource.h>

//#include <boost/program_options.hpp>
#include <thread>
#include <iostream>
#include <malloc.h>

size_t s_test = 0;
bool s_exit = false;
boost::asio::io_service s_async_io_service;

struct Memory
{
    size_t allocation_count = 0;
    size_t free_count = 0;
} s_memory;

namespace boost
{
	void throw_exception(std::exception const & e)
	{
        QLOGE("boost::exception {}", e.what());
		throw e;
    }
}

namespace silk
{
void execute_async_call(std::function<void()> f)
{
    s_async_io_service.post(f);
}
}

///////////////////////////////////////////////////////////////////////////////////////////////////

/* This prints an "Assertion failed" message and aborts.  */
void __assert_fail(const char *__assertion, const char *__file, unsigned int __line, const char *__function)
{
    QASSERT_MSG(false, "assert: {}:{}: {}: {}", __file, __line, __function, __assertion);
}

//static void* malloc_hook(size_t size, const void* caller)
//{
//    s_memory.allocation_count++;
//    __malloc_hook = nullptr;
//    printf("\n%d, %d", int(s_memory.allocation_count), int(s_memory.free_count));
//    fflush(stdout);
//    void* ptr = malloc(size);
//    __malloc_hook = &malloc_hook;
//    return ptr;
//}
//void free_hook(void* ptr, const void* caller)
//{
//    s_memory.free_count++;
//    __free_hook = nullptr;
//    printf("\n%d, %d", int(s_memory.allocation_count), int(s_memory.free_count));
//    fflush(stdout);
//    free(ptr);
//    __free_hook = &free_hook;
//}

// Define the function to be called when ctrl-c (SIGINT) signal is sent to process
void signal_handler(int signum)
{
    if (s_exit)
    {
        QLOGI("Forcing an exit due to signal {}", signum);
        abort();
    }
    s_exit = true;
    QLOGI("Exitting due to signal {}", signum);
}

void out_of_memory_handler()
{
    QLOGE("Out of memory");
    std::abort();
}

int main(int argc, char const* argv[])
{
    signal(SIGINT, signal_handler); // Trap basic signals (exit cleanly)
    signal(SIGKILL, signal_handler);
    signal(SIGUSR1, signal_handler);
    signal(SIGQUIT, signal_handler);
//    signal(SIGABRT, signal_handler);
    signal(SIGTERM, signal_handler);

    //__malloc_hook = &malloc_hook;
    //__free_hook = &free_hook;

    //set the new_handler
    std::set_new_handler(out_of_memory_handler);

    std::srand(std::time(0));

    q::logging::add_logger(q::logging::Logger_uptr(new q::logging::Console_Logger()));
    q::logging::set_decorations(q::logging::Decorations(q::logging::Decoration::TIMESTAMP, q::logging::Decoration::LEVEL, q::logging::Decoration::TOPIC));

    QLOG_TOPIC("silk");

//    namespace po = boost::program_options;

//	po::options_description desc("Options");
//	desc.add_options()
//		("help", "produce help message")
//        ("blind", "no camera")
//        ("test", po::value<size_t>(), "test");

//	po::variables_map vm;
//	po::store(po::parse_command_line(argc, argv, desc), vm);
//	po::notify(vm);

//	if (vm.count("help"))
//	{
//        std::cout << desc << "\n";
//		return 1;
//	}

//    s_test = vm.count("test") ? vm["test"].as<size_t>() : size_t(0);
//    //bool blind = vm.count("blind") != 0;

    QLOGI("Creating io_service thread");

    boost::shared_ptr<boost::asio::io_service::work> async_work(new boost::asio::io_service::work(s_async_io_service));
    auto async_thread = boost::thread([]() { s_async_io_service.run(); });

#if defined RASPBERRY_PI
    {
        int policy = SCHED_FIFO;
        struct sched_param param;
        param.sched_priority = sched_get_priority_max(policy);
        if (pthread_setschedparam(pthread_self(), policy, &param) != 0)
        {
            perror("Failed to set priority for main thread");
            //exit(EXIT_FAILURE);
        }
        policy = SCHED_IDLE;
        param.sched_priority = sched_get_priority_min(policy);
        if (pthread_setschedparam(async_thread.native_handle(), policy, &param) != 0)
        {
            perror("Failed to set priority for async thread");
            //exit(EXIT_FAILURE);
        }
    }
#endif

    try
    {
        silk::HAL hal;
        silk::RC_Comms rc_comms(hal);
        silk::GS_Comms gs_comms(hal);

        if (!hal.init(rc_comms, gs_comms))
        {
            QLOGE("Hardware failure! Aborting");
            goto exit;
        }

        if (!rc_comms.start("wlan1", 3))
        {
            QLOGW("Cannot start rc communication channel!");
//            goto exit;
        }

        if (!gs_comms.start_udp(8005, 8006))
        {
            QLOGE("Cannot start gs communication channel! Aborting");
            goto exit;
        }

//        while (!s_exit)
//        {
//            std::this_thread::sleep_for(std::chrono::milliseconds(1000));
//            QLOGI("Waiting for comms to connect...");
//            if (comms.is_connected())
//            {
//                break;
//            }
//        }

        QLOGI("All systems up. Ready to fly...");

        {
            constexpr std::chrono::microseconds PERIOD(5000);
            auto last = Clock::now();
            while (!s_exit)
            {
                auto start = Clock::now();
                auto dt = start - last;
                last = start;
#ifdef NDEBUG
                if (dt > std::chrono::milliseconds(5))
#else
                if (dt > std::chrono::milliseconds(50))
#endif
                {
                    QLOGW("Process Latency of {}!!!!!", dt);
                }
                gs_comms.process();
                rc_comms.process();
                hal.process();

                //No sleeping here!!! process as fast as possible as the nodes are not always in the ideal order
                // and out of order nodes will be processes next 'frame'. So the quicker the frames, the smaller the lag between nodes
#ifndef RASPBERRY_PI
                std::this_thread::sleep_for(std::chrono::milliseconds(1));
#endif

                {
                    static Clock::time_point last_timestamp = Clock::now();
                    auto now = Clock::now();
                    auto dt = now - last_timestamp;
                    last_timestamp = now;
                    static Clock::duration min_dt, max_dt, avg_dt;
                    static int xxx = 0;
                    min_dt = std::min(min_dt, dt);
                    max_dt = std::max(max_dt, dt);
                    avg_dt += dt;
                    xxx++;
                    static Clock::time_point xxx_timestamp = Clock::now();
                    if (now - xxx_timestamp >= std::chrono::milliseconds(1000))
                    {
                        xxx_timestamp = now;

                        QLOGI("min {}, max {}, avg {}", min_dt, max_dt, avg_dt/ xxx);
                        min_dt = dt;
                        max_dt = dt;
                        avg_dt = std::chrono::milliseconds(0);

                        xxx = 0;
                    }
                }
            }
        }

exit:
        QLOGI("Stopping everything");

        //stop threads
        async_work.reset();
        s_async_io_service.stop();
        if (async_thread.joinable())
        {
            std::this_thread::yield();
            async_thread.join();
        }
        hal.shutdown();
    }
    catch (std::exception const& e)
    {
        QLOGE("exception: {}", e.what());
        abort();
    }

    QLOGI("Closing");
}

<commit_msg>removed too verbose logs<commit_after>#include "FCStdAfx.h"
#include "HAL.h"
#include "RC_Comms.h"
#include "GS_Comms.h"
#include "utils/Clock.h"

#include <boost/asio.hpp>
#include <boost/thread.hpp>

#include <sys/time.h>
#include <sys/resource.h>

//#include <boost/program_options.hpp>
#include <thread>
#include <iostream>
#include <malloc.h>

size_t s_test = 0;
bool s_exit = false;
boost::asio::io_service s_async_io_service;

struct Memory
{
    size_t allocation_count = 0;
    size_t free_count = 0;
} s_memory;

namespace boost
{
	void throw_exception(std::exception const & e)
	{
        QLOGE("boost::exception {}", e.what());
		throw e;
    }
}

namespace silk
{
void execute_async_call(std::function<void()> f)
{
    s_async_io_service.post(f);
}
}

///////////////////////////////////////////////////////////////////////////////////////////////////

/* This prints an "Assertion failed" message and aborts.  */
void __assert_fail(const char *__assertion, const char *__file, unsigned int __line, const char *__function)
{
    QASSERT_MSG(false, "assert: {}:{}: {}: {}", __file, __line, __function, __assertion);
}

//static void* malloc_hook(size_t size, const void* caller)
//{
//    s_memory.allocation_count++;
//    __malloc_hook = nullptr;
//    printf("\n%d, %d", int(s_memory.allocation_count), int(s_memory.free_count));
//    fflush(stdout);
//    void* ptr = malloc(size);
//    __malloc_hook = &malloc_hook;
//    return ptr;
//}
//void free_hook(void* ptr, const void* caller)
//{
//    s_memory.free_count++;
//    __free_hook = nullptr;
//    printf("\n%d, %d", int(s_memory.allocation_count), int(s_memory.free_count));
//    fflush(stdout);
//    free(ptr);
//    __free_hook = &free_hook;
//}

// Define the function to be called when ctrl-c (SIGINT) signal is sent to process
void signal_handler(int signum)
{
    if (s_exit)
    {
        QLOGI("Forcing an exit due to signal {}", signum);
        abort();
    }
    s_exit = true;
    QLOGI("Exitting due to signal {}", signum);
}

void out_of_memory_handler()
{
    QLOGE("Out of memory");
    std::abort();
}

int main(int argc, char const* argv[])
{
    signal(SIGINT, signal_handler); // Trap basic signals (exit cleanly)
    signal(SIGKILL, signal_handler);
    signal(SIGUSR1, signal_handler);
    signal(SIGQUIT, signal_handler);
//    signal(SIGABRT, signal_handler);
    signal(SIGTERM, signal_handler);

    //__malloc_hook = &malloc_hook;
    //__free_hook = &free_hook;

    //set the new_handler
    std::set_new_handler(out_of_memory_handler);

    std::srand(std::time(0));

    q::logging::add_logger(q::logging::Logger_uptr(new q::logging::Console_Logger()));
    q::logging::set_decorations(q::logging::Decorations(q::logging::Decoration::TIMESTAMP, q::logging::Decoration::LEVEL, q::logging::Decoration::TOPIC));

    QLOG_TOPIC("silk");

//    namespace po = boost::program_options;

//	po::options_description desc("Options");
//	desc.add_options()
//		("help", "produce help message")
//        ("blind", "no camera")
//        ("test", po::value<size_t>(), "test");

//	po::variables_map vm;
//	po::store(po::parse_command_line(argc, argv, desc), vm);
//	po::notify(vm);

//	if (vm.count("help"))
//	{
//        std::cout << desc << "\n";
//		return 1;
//	}

//    s_test = vm.count("test") ? vm["test"].as<size_t>() : size_t(0);
//    //bool blind = vm.count("blind") != 0;

    QLOGI("Creating io_service thread");

    boost::shared_ptr<boost::asio::io_service::work> async_work(new boost::asio::io_service::work(s_async_io_service));
    auto async_thread = boost::thread([]() { s_async_io_service.run(); });

#if defined RASPBERRY_PI
    {
        int policy = SCHED_FIFO;
        struct sched_param param;
        param.sched_priority = sched_get_priority_max(policy);
        if (pthread_setschedparam(pthread_self(), policy, &param) != 0)
        {
            perror("Failed to set priority for main thread");
            //exit(EXIT_FAILURE);
        }
        policy = SCHED_IDLE;
        param.sched_priority = sched_get_priority_min(policy);
        if (pthread_setschedparam(async_thread.native_handle(), policy, &param) != 0)
        {
            perror("Failed to set priority for async thread");
            //exit(EXIT_FAILURE);
        }
    }
#endif

    try
    {
        silk::HAL hal;
        silk::RC_Comms rc_comms(hal);
        silk::GS_Comms gs_comms(hal);

        if (!hal.init(rc_comms, gs_comms))
        {
            QLOGE("Hardware failure! Aborting");
            goto exit;
        }

        if (!rc_comms.start("wlan1", 3))
        {
            QLOGW("Cannot start rc communication channel!");
//            goto exit;
        }

        if (!gs_comms.start_udp(8005, 8006))
        {
            QLOGE("Cannot start gs communication channel! Aborting");
            goto exit;
        }

//        while (!s_exit)
//        {
//            std::this_thread::sleep_for(std::chrono::milliseconds(1000));
//            QLOGI("Waiting for comms to connect...");
//            if (comms.is_connected())
//            {
//                break;
//            }
//        }

        QLOGI("All systems up. Ready to fly...");

        {
            constexpr std::chrono::microseconds PERIOD(5000);
            auto last = Clock::now();
            while (!s_exit)
            {
                auto start = Clock::now();
                auto dt = start - last;
                last = start;
#ifdef NDEBUG
                if (dt > std::chrono::milliseconds(5))
#else
                if (dt > std::chrono::milliseconds(50))
#endif
                {
                    QLOGW("Process Latency of {}!!!!!", dt);
                }
                gs_comms.process();
                rc_comms.process();
                hal.process();

                //No sleeping here!!! process as fast as possible as the nodes are not always in the ideal order
                // and out of order nodes will be processes next 'frame'. So the quicker the frames, the smaller the lag between nodes
#ifndef RASPBERRY_PI
                std::this_thread::sleep_for(std::chrono::milliseconds(1));
#endif

//                {
//                    static Clock::time_point last_timestamp = Clock::now();
//                    auto now = Clock::now();
//                    auto dt = now - last_timestamp;
//                    last_timestamp = now;
//                    static Clock::duration min_dt, max_dt, avg_dt;
//                    static int xxx = 0;
//                    min_dt = std::min(min_dt, dt);
//                    max_dt = std::max(max_dt, dt);
//                    avg_dt += dt;
//                    xxx++;
//                    static Clock::time_point xxx_timestamp = Clock::now();
//                    if (now - xxx_timestamp >= std::chrono::milliseconds(1000))
//                    {
//                        xxx_timestamp = now;

//                        QLOGI("min {}, max {}, avg {}", min_dt, max_dt, avg_dt/ xxx);
//                        min_dt = dt;
//                        max_dt = dt;
//                        avg_dt = std::chrono::milliseconds(0);

//                        xxx = 0;
//                    }
//                }
            }
        }

exit:
        QLOGI("Stopping everything");

        //stop threads
        async_work.reset();
        s_async_io_service.stop();
        if (async_thread.joinable())
        {
            std::this_thread::yield();
            async_thread.join();
        }
        hal.shutdown();
    }
    catch (std::exception const& e)
    {
        QLOGE("exception: {}", e.what());
        abort();
    }

    QLOGI("Closing");
}

<|endoftext|>


<commit_before>#include "testApp.h"

using namespace ofxCv;
using namespace cv;

void testApp::setup() {

	ofSetVerticalSync(true);
	ofEnableSmoothing();
	ofBackground(ofColor::black);

	internet = false;

	if(internet){
		std::string requete;
		std::cout << "Que voulez-vous dessiner ?" << std::endl;
		std::cin >> requete ;

		Flickr::downloadImageFromFlickr(requete);
		painting.loadImage("tmp.jpg");

	  	wt.setCity("Nantes") ;

		std::cout << "Temperature (kelvin) : " << wt.getTemperature() << std::endl;
		std::cout << "Temperature (celcius) : " << wt.getTemperature()-273 << std::endl;
		std::cout << "Humidity : " << wt.getHumidity() << std::endl;
		std::cout << "Pressure : " << wt.getPressure() << std::endl;
		std::cout << "Pressure (normalisation) : " << wt.getPressure()-1013 << std::endl;
	}
	else
		painting.loadImage("img/wolkswagen.jpg");

	painting.resize(500,600);
	it_treshold=0;
	screenImg.allocate(500, 600, OF_IMAGE_COLOR);
	allThresholdsDone = false;
	gifEncoder.setup(500,600,.25, 256);
	//ofAddListener(ofxGifEncoder::OFX_GIF_SAVE_FINISHED, this, &testApp::onGifSaved);
}

void testApp::update() {

	if(!allThresholdsDone){
		markings = contourPainting();
		screenImg.grabScreen(0,0,500,600);

		if(it_treshold%10 == 0)
		gifEncoder.addFrame(screenImg.getPixels(),500,600);

		if(markings.empty()){
			allThresholdsDone = true ;
			string name = "result";
			screenImg.saveImage(name+".jpg");
			std::cout << "Image saved as " << name+".jpg" << std::endl;
			std::cout << "Saving GIF ... " << std::endl;
			gifEncoder.save(name+".gif");
		}

		//std::cout << it_treshold << std::endl;
		it_treshold++;
	}
}

void testApp::draw() {

	screenImg.draw(0,0);
	painting.draw(ofGetWidth()/2,0);

	for(auto i = 0u; i < markings.size(); i++)
	{
		markings[i]->draw();
		delete markings[i];
	}
	markings.clear();

}

vector<ofxMarking *> testApp::contourPainting(){

	vector<ofxMarking *> result;

	ofxCv::ContourFinder contourFinder;
	contourFinder.setThreshold(it_treshold);
	contourFinder.setFindHoles(true);
	contourFinder.findContours(painting);

	for(auto &c : contourFinder.getContours()){

		BrushLine line;

		if(internet)
			line = BrushLine(ofColor::black,wt.getHumidity()/10,wt.getPressure()-1013);
		else
			line = BrushLine(ofColor::black,5,255);

		for(auto &p : c){

			ofColor color = painting.getColor(p.x,p.y);
			color.setSaturation((wt.getTemperature()-273)*255/30);
			line.lineTo(p.x,p.y,color);
		}
		line.lineEnd(&result);
	}

	return result;
}

ofColor testApp::filterColor(int x,int y,int width_filter){

	int size_filter = width_filter*width_filter*4+1;
	ofColor color = painting.getColor(x,y)/size_filter;

	for(int i=1;i<=width_filter;i++){
		for(int j=1;j<=width_filter;j++){
			color += painting.getColor(x+i,y+j)/size_filter;
			color += painting.getColor(x-i,y-j)/size_filter;
			color += painting.getColor(x+i,y)/size_filter;
			color += painting.getColor(x,y-j)/size_filter;
		}
	}
	return color;
}

void testApp::onGifSaved(const std::string &fileName) {
    std::cout << "GIF saved as " << fileName << std::endl;
}

void testApp::exit()
{
    for(auto i = 0u; i < markings.size(); i++)
    {
        delete markings[i];
    }
    markings.clear();

}

//--------------------------------------------------------------
void testApp::keyPressed(int key)
{

}

//--------------------------------------------------------------
void testApp::keyReleased(int key)
{

}

//--------------------------------------------------------------
void testApp::mouseMoved(int x, int y)
{

}

//--------------------------------------------------------------
void testApp::mouseDragged(int x, int y, int button)
{
	//drawing.lineTo(mouseX,mouseY);
}

//--------------------------------------------------------------
void testApp::mousePressed(int x, int y, int button)
{
	//drawing = BrushLine(ofColor::red,10,100);
}

//--------------------------------------------------------------
void testApp::mouseReleased(int x, int y, int button)
{
	//drawing.lineEnd();
}

//--------------------------------------------------------------
void testApp::windowResized(int w, int h)
{

}

//--------------------------------------------------------------
void testApp::gotMessage(ofMessage msg)
{

}

//--------------------------------------------------------------
void testApp::dragEvent(ofDragInfo dragInfo)
{

}
<commit_msg>Correctif couleur pas prise en compte en mode déconnecté<commit_after>#include "testApp.h"

using namespace ofxCv;
using namespace cv;

void testApp::setup() {

	ofSetVerticalSync(true);
	ofEnableSmoothing();
	ofBackground(ofColor::black);

	internet = false;

	if(internet){
		std::string requete;
		std::cout << "Que voulez-vous dessiner ?" << std::endl;
		std::cin >> requete ;

		Flickr::downloadImageFromFlickr(requete);
		painting.loadImage("tmp.jpg");

	  	wt.setCity("Nantes") ;

		std::cout << "Temperature (kelvin) : " << wt.getTemperature() << std::endl;
		std::cout << "Temperature (celcius) : " << wt.getTemperature()-273 << std::endl;
		std::cout << "Humidity : " << wt.getHumidity() << std::endl;
		std::cout << "Pressure : " << wt.getPressure() << std::endl;
		std::cout << "Pressure (normalisation) : " << wt.getPressure()-1013 << std::endl;
	}
	else
		painting.loadImage("img/wolkswagen.jpg");

	painting.resize(500,600);
	it_treshold=0;
	screenImg.allocate(500, 600, OF_IMAGE_COLOR);
	allThresholdsDone = false;
	gifEncoder.setup(500,600,.25, 256);
	//ofAddListener(ofxGifEncoder::OFX_GIF_SAVE_FINISHED, this, &testApp::onGifSaved);
}

void testApp::update() {

	if(!allThresholdsDone){
		markings = contourPainting();
		screenImg.grabScreen(0,0,500,600);

		if(it_treshold%10 == 0)
		gifEncoder.addFrame(screenImg.getPixels(),500,600);

		if(markings.empty()){
			allThresholdsDone = true ;
			string name = "result";
			screenImg.saveImage(name+".jpg");
			std::cout << "Image saved as " << name+".jpg" << std::endl;
			std::cout << "Saving GIF ... " << std::endl;
			gifEncoder.save(name+".gif");
		}

		//std::cout << it_treshold << std::endl;
		it_treshold++;
	}
}

void testApp::draw() {

	screenImg.draw(0,0);
	painting.draw(ofGetWidth()/2,0);

	for(auto i = 0u; i < markings.size(); i++)
	{
		markings[i]->draw();
		delete markings[i];
	}
	markings.clear();

}

vector<ofxMarking *> testApp::contourPainting(){

	vector<ofxMarking *> result;

	ofxCv::ContourFinder contourFinder;
	contourFinder.setThreshold(it_treshold);
	contourFinder.setFindHoles(true);
	contourFinder.findContours(painting);

	for(auto &c : contourFinder.getContours()){

		BrushLine line;

		if(internet)
			line = BrushLine(ofColor::black,wt.getHumidity()/10,wt.getPressure()-1013);
		else
			line = BrushLine();

		for(auto &p : c){

			ofColor color = painting.getColor(p.x,p.y);
			if(internet)
				color.setSaturation((wt.getTemperature()-273)*255/30);
			line.lineTo(p.x,p.y,color);
		}
		line.lineEnd(&result);
	}

	return result;
}

ofColor testApp::filterColor(int x,int y,int width_filter){

	int size_filter = width_filter*width_filter*4+1;
	ofColor color = painting.getColor(x,y)/size_filter;

	for(int i=1;i<=width_filter;i++){
		for(int j=1;j<=width_filter;j++){
			color += painting.getColor(x+i,y+j)/size_filter;
			color += painting.getColor(x-i,y-j)/size_filter;
			color += painting.getColor(x+i,y)/size_filter;
			color += painting.getColor(x,y-j)/size_filter;
		}
	}
	return color;
}

void testApp::onGifSaved(const std::string &fileName) {
    std::cout << "GIF saved as " << fileName << std::endl;
}

void testApp::exit()
{
    for(auto i = 0u; i < markings.size(); i++)
    {
        delete markings[i];
    }
    markings.clear();

}

//--------------------------------------------------------------
void testApp::keyPressed(int key)
{

}

//--------------------------------------------------------------
void testApp::keyReleased(int key)
{

}

//--------------------------------------------------------------
void testApp::mouseMoved(int x, int y)
{

}

//--------------------------------------------------------------
void testApp::mouseDragged(int x, int y, int button)
{
	//drawing.lineTo(mouseX,mouseY);
}

//--------------------------------------------------------------
void testApp::mousePressed(int x, int y, int button)
{
	//drawing = BrushLine(ofColor::red,10,100);
}

//--------------------------------------------------------------
void testApp::mouseReleased(int x, int y, int button)
{
	//drawing.lineEnd();
}

//--------------------------------------------------------------
void testApp::windowResized(int w, int h)
{

}

//--------------------------------------------------------------
void testApp::gotMessage(ofMessage msg)
{

}

//--------------------------------------------------------------
void testApp::dragEvent(ofDragInfo dragInfo)
{

}
<|endoftext|>