<commit_before>/**
 * \file
 * \brief file reader
 *
 * \author Dmitriy Kargapolov <dmitriy dot kargapolov at gmail dot com>
 * \since 27 Jul 2012
 *
 * Copyright (C) 2012 Dmitriy Kargapolov <dmitriy.kargapolov@gmail.com>
 * Copyright (C) 2012 Serge Aleynikov <saleyn@gmail.com>
 *
 * Use, modification and distribution are subject to the Boost Software
 * License, Version 1.0 (See accompanying file LICENSE_1_0.txt or copy
 * at http://www.boost.org/LICENSE_1_0.txt)
 */

#ifndef _UTIL_FILE_READER_HPP_
#define _UTIL_FILE_READER_HPP_

#include <iostream>
#include <fstream>
#include <boost/noncopyable.hpp>
#include <util/buffer.hpp>

namespace util {

/**
 * \brief Basic file reader with pre-allocated buffer.
 */
template<size_t BufSize = 1024 * 1024>
class basic_file_reader : private boost::noncopyable {
    std::string m_fname;
    std::ifstream m_file;
    util::basic_io_buffer<BufSize> m_buf;
    size_t m_offset;
    bool m_open;

public:
    /// default constructor
    basic_file_reader() : m_offset(0), m_open(false) {}

    /// constructor opening file for reading
    basic_file_reader(const std::string& a_fname) throw (std::ifstream::failure)
        : m_offset(0), m_open(false)
    {
        open(a_fname);
    }

    /// destructor
    ~basic_file_reader() {
        if (!m_open) return;
        try {
            m_file.close();
        } catch (...) {
        }
    }

    /// open file for reading
    void open(const std::string& a_fname) throw (std::ifstream::failure) {
        if (m_open) return;
        // make sure exception thrown in case of error
        m_file.exceptions(std::ifstream::failbit | std::ifstream::badbit);
        m_file.open(a_fname.c_str(), std::ios::in | std::ios::binary);
        // further read can set failbit in case there is not enough data
        // this case should not throw an exception in our class
        m_file.exceptions(std::ifstream::badbit);
        m_open = true;
        m_fname = a_fname;
        m_buf.reset();
        BOOST_ASSERT(m_buf.capacity() > 0);
    }

    /// set initial read position
    void seek(size_t a_offset) throw (std::ifstream::failure) {
        if (!m_open) return;
        m_file.seekg(a_offset, std::ios::beg);
        m_offset = m_file.tellg();
    }

    /// clear error control state so read could be resumed
    void clear() { m_file.clear(); }

    /// offset at which read start
    size_t offset() const { return m_offset; }

    /// current number of bytes available to read.
    size_t size() const { return m_buf.size(); }

    /// current read pointer.
    const char* rd_ptr() const { return m_buf.rd_ptr(); }

    /// confirm consuming of n bytes
    void commit(size_t n) { m_buf.read(n); }

    /// read portion of file into internal buffer
    /// if a_crunch == true, crunch buffer before reading
    bool read(bool a_crunch = true) throw (std::ifstream::failure, io_error) {
        if (!m_open || !m_file.is_open())
            return false;
        if (a_crunch)
            m_buf.crunch();
        while (true) {
            BOOST_ASSERT(m_buf.capacity() > 0);
            m_file.read(m_buf.wr_ptr(), m_buf.capacity());
            int n = m_file.gcount();
            if (n == 0) {
                if (m_file.good()) continue;
                if (m_file.eof()) return false;
                // this should never happen since we have set badbit
                throw(io_error(errno, "Unexpected error reading ", m_fname));
            }
            m_buf.commit(n);
            return true;
        }
    }
};

/**
 * \brief File reader with data payload codec and input iterator.
 */
template<typename Codec, size_t BufSize = 1024 * 1024>
class data_file_reader : public basic_file_reader<BufSize> {

    typedef Codec codec_t;
    typedef typename codec_t::data_t data_t;
    typedef basic_file_reader<BufSize> base;

    codec_t m_codec;
    size_t m_data_offset;

    friend class iterator;

public:
    /// create file reader with specific or default codec object
    data_file_reader(const codec_t& a_codec = codec_t())
        : m_codec(a_codec)
        , m_data_offset(base::offset())
    {}

    /// create reader object and open file for reading
    data_file_reader(const std::string& a_fname,
                     const codec_t& a_codec = codec_t())
            throw (std::ifstream::failure)
        : base(a_fname), m_codec(a_codec)
        , m_data_offset(base::offset())
    {}

    /// create reader object and open file for reading at given offset
    data_file_reader(const std::string& a_fname, size_t a_offset,
                     const codec_t& a_codec = codec_t())
            throw (std::ifstream::failure)
        : base(a_fname), m_codec(a_codec)
        , m_data_offset(base::offset())
    {
        seek(a_offset);
    }

    /// set initial read position
    void seek(size_t a_offset) throw (std::ifstream::failure) {
        base::seek(a_offset);
        m_data_offset = base::offset();
    }

    /// offset for the next record to decode
    size_t data_offset() const { return m_data_offset; }

    /// iterator for reading sequence of records
    class iterator : public std::iterator<std::input_iterator_tag, data_t> {

        data_file_reader& m_freader;
        codec_t& m_codec;
        size_t& m_data_offset;
        data_t m_data;
        bool m_end, m_error;

    public:
        iterator(data_file_reader& a_freader, bool a_end = false)
            : m_freader(a_freader)
            , m_codec(m_freader.m_codec)
            , m_data_offset(m_freader.m_data_offset)
            , m_end(a_end)
            , m_error(false)
        {
            if (!m_end) m_freader.clear();
        }

        iterator& operator++() throw (std::ifstream::failure) {
            while (!m_end) {
                ssize_t n = m_codec.decode(m_data,
                    m_freader.rd_ptr(), m_freader.size(), m_data_offset);
                if (n > 0) {
                    m_data_offset += n;
                    m_freader.commit(n);
                    break;
                }
                if (n < 0) {
                    m_end = true;
                    m_error = true;
                    break;
                }
                if (!m_freader.read()) {
                    m_end = true;
                    break;
                }
            }
            return *this;
        }

        iterator operator++(int) throw (std::ifstream::failure) {
            iterator tmp(*this); operator++(); return tmp;
        }

        bool operator==(const iterator& rhs) const {
            return (m_end == true && m_end == rhs.m_end)
                || (m_end == false && m_end == rhs.m_end &&
                    m_error == false && m_error == rhs.m_error &&
                    m_data_offset == rhs.m_data_offset);
        }

        bool operator!=(const iterator& rhs) const {
            return !(*this == rhs);
        }

        data_t& operator*() { return m_data; }
        const data_t& operator*() const { return m_data; }
        data_t* operator->() { return &m_data; }
        const data_t* operator->() const { return &m_data; }

    };

    typedef const iterator const_iterator;

    /// get input iterator at currect read position
    iterator begin() { return ++iterator(*this); }
    const_iterator begin() const { return ++iterator(*this); }

    /// end-of-read position iterator
    iterator end() { return iterator(*this, true); }
    const_iterator end() const { return iterator(*this, true); }
};

} // namespace util

#endif // _UTIL_FILE_READER_HPP_
<commit_msg>minor corrections<commit_after>/**
 * \file
 * \brief file reader
 *
 * \author Dmitriy Kargapolov <dmitriy dot kargapolov at gmail dot com>
 * \since 27 Jul 2012
 *
 * Copyright (C) 2012 Dmitriy Kargapolov <dmitriy.kargapolov@gmail.com>
 * Copyright (C) 2012 Serge Aleynikov <saleyn@gmail.com>
 *
 * Use, modification and distribution are subject to the Boost Software
 * License, Version 1.0 (See accompanying file LICENSE_1_0.txt or copy
 * at http://www.boost.org/LICENSE_1_0.txt)
 */

#ifndef _UTIL_FILE_READER_HPP_
#define _UTIL_FILE_READER_HPP_

#include <iostream>
#include <fstream>
#include <boost/noncopyable.hpp>
#include <util/buffer.hpp>

namespace util {

/**
 * \brief Basic file reader with pre-allocated buffer.
 */
template<size_t BufSize = 1024 * 1024>
class basic_file_reader : private boost::noncopyable {
    std::string m_fname;
    std::ifstream m_file;
    util::basic_io_buffer<BufSize> m_buf;
    size_t m_offset;
    bool m_open;

public:
    /// default constructor
    basic_file_reader() : m_offset(0), m_open(false) {}

    /// constructor opening file for reading
    basic_file_reader(const std::string& a_fname) throw (std::ifstream::failure)
        : m_offset(0), m_open(false)
    {
        open(a_fname);
    }

    /// destructor
    ~basic_file_reader() {
        if (!m_open) return;
        try {
            m_file.close();
        } catch (...) {
        }
    }

    /// open file for reading
    void open(const std::string& a_fname) throw (std::ifstream::failure) {
        if (m_open) return;
        // make sure exception thrown in case of error
        m_file.exceptions(std::ifstream::failbit | std::ifstream::badbit);
        m_file.open(a_fname.c_str(), std::ios::in | std::ios::binary);
        // further read can set failbit in case there is not enough data
        // this case should not throw an exception in our class
        m_file.exceptions(std::ifstream::badbit);
        m_open = true;
        m_fname = a_fname;
        m_buf.reset();
        BOOST_ASSERT(m_buf.capacity() > 0);
    }

    /// set initial read position
    void seek(size_t a_offset) throw (std::ifstream::failure) {
        if (!m_open) return;
        m_file.seekg(a_offset, std::ios::beg);
        m_offset = m_file.tellg();
    }

    /// clear error control state so read could be resumed
    void clear() { m_file.clear(); }

    /// offset at which read start
    size_t offset() const { return m_offset; }

    /// current number of bytes available to read.
    size_t size() const { return m_buf.size(); }

    /// current read pointer.
    const char* rd_ptr() const { return m_buf.rd_ptr(); }

    /// confirm consuming of n bytes
    void commit(size_t n) { m_buf.read(n); }

    /// read portion of file into internal buffer
    /// if a_crunch == true, crunch buffer before reading
    bool read(bool a_crunch = true) throw (std::ifstream::failure, io_error) {
        if (!m_open || !m_file.is_open())
            return false;
        if (a_crunch)
            m_buf.crunch();
        while (true) {
            BOOST_ASSERT(m_buf.capacity() > 0);
            m_file.read(m_buf.wr_ptr(), m_buf.capacity());
            int n = m_file.gcount();
            if (n == 0) {
                if (m_file.good()) continue;
                if (m_file.eof()) return false;
                // this should never happen since we have set badbit
                throw(io_error(errno, "Unexpected error reading ", m_fname));
            }
            m_buf.commit(n);
            return true;
        }
    }
};

/**
 * \brief File reader with data payload codec and input iterator.
 */
template<typename Codec, size_t BufSize = 1024 * 1024>
class data_file_reader : public basic_file_reader<BufSize> {

    typedef Codec codec_t;
    typedef typename codec_t::data_t data_t;
    typedef basic_file_reader<BufSize> base;

    codec_t m_codec;
    size_t m_data_offset;

    friend class iterator;

public:
    /// create file reader with specific or default codec object
    data_file_reader(const codec_t& a_codec = codec_t())
        : m_codec(a_codec)
        , m_data_offset(base::offset())
    {}

    /// create reader object and open file for reading
    data_file_reader(const std::string& a_fname,
                     const codec_t& a_codec = codec_t())
            throw (std::ifstream::failure)
        : base(a_fname), m_codec(a_codec)
        , m_data_offset(base::offset())
    {}

    /// create reader object and open file for reading at given offset
    data_file_reader(const std::string& a_fname, size_t a_offset,
                     const codec_t& a_codec = codec_t())
            throw (std::ifstream::failure)
        : base(a_fname), m_codec(a_codec)
        , m_data_offset(base::offset())
    {
        seek(a_offset);
    }

    /// set initial read position
    void seek(size_t a_offset) throw (std::ifstream::failure) {
        base::seek(a_offset);
        m_data_offset = base::offset();
    }

    /// offset for the next record to decode
    size_t data_offset() const { return m_data_offset; }

    /// iterator for reading sequence of records
    class iterator : public std::iterator<std::input_iterator_tag, data_t> {

        data_file_reader& m_freader;
        codec_t& m_codec;
        size_t& m_data_offset;
        data_t m_data;
        bool m_end, m_error;

    public:
        iterator(data_file_reader& a_freader, bool a_end = false)
            : m_freader(a_freader)
            , m_codec(m_freader.m_codec)
            , m_data_offset(m_freader.m_data_offset)
            , m_end(a_end)
            , m_error(false)
        {
            if (!m_end) m_freader.clear();
        }

        iterator& operator++() throw (std::ifstream::failure, io_error) {
            while (!m_end) {
                ssize_t n = m_codec.decode(m_data,
                    m_freader.rd_ptr(), m_freader.size(), m_data_offset);
                if (n > 0) {
                    m_data_offset += n;
                    m_freader.commit(n);
                    break;
                }
                if (n < 0) {
                    m_end = true;
                    m_error = true;
                    break;
                }
                if (!m_freader.read()) {
                    m_end = true;
                    break;
                }
            }
            return *this;
        }

        iterator operator++(int) throw (std::ifstream::failure, io_error) {
            iterator tmp(*this); operator++(); return tmp;
        }

        bool operator==(const iterator& rhs) const {
            return (m_end == true && m_end == rhs.m_end)
                || (m_end == false && m_end == rhs.m_end &&
                    m_error == false && m_error == rhs.m_error &&
                    m_data_offset == rhs.m_data_offset);
        }

        bool operator!=(const iterator& rhs) const {
            return !(*this == rhs);
        }

        data_t& operator*() { return m_data; }
        const data_t& operator*() const { return m_data; }
        data_t* operator->() { return &m_data; }
        const data_t* operator->() const { return &m_data; }

    };

    typedef const iterator const_iterator;

    /// get input iterator at currect read position
    iterator begin() throw (std::ifstream::failure, io_error) {
        return ++iterator(*this);
    }
    const_iterator begin() const throw (std::ifstream::failure, io_error) {
        return ++iterator(*this);
    }

    /// end-of-read position iterator
    iterator end() { return iterator(*this, true); }
    const_iterator end() const { return iterator(*this, true); }
};

} // namespace util

#endif // _UTIL_FILE_READER_HPP_
<|endoftext|>


<commit_before>#ifndef VSMC_CORE_WEIGHT_HPP
#define VSMC_CORE_WEIGHT_HPP

#include <vsmc/internal/common.hpp>
#include <vsmc/utility/cxxblas.hpp>

namespace vsmc {

/// \brief Weight set class
/// \ingroup Core
template <typename T>
class WeightSet
{
    public :

    typedef typename traits::SizeTypeTrait<T>::type size_type;
    typedef typename traits::DDotTypeTrait<T>::type ddot_type;

    explicit WeightSet (size_type N) :
        size_(N), ess_(static_cast<double>(N)), weight_(N), log_weight_(N) {}

    size_type resample_size () const
    {
        return size_;
    }

    template <typename OutputIter>
    OutputIter read_resample_weight (OutputIter first) const
    {
        return read_weight(first);
    }

    template <typename RandomIter>
    RandomIter read_resample_weight (RandomIter first, int stride) const
    {
        return read_weight(first, stride);
    }

    /// \brief Read normalized weights through an output iterator
    template <typename OutputIter>
    OutputIter read_weight (OutputIter first) const
    {
        return std::copy(weight_.begin(), weight_.end(), first);
    }

    /// \brief Read normalized weights through a random access iterator with
    /// (possible non-uniform stride)
    template <typename RandomIter>
    RandomIter read_weight (RandomIter first, int stride) const
    {
        for (size_type i = 0; i != size_; ++i, first += stride)
            *first = weight_[i];

        return first;
    }

    /// \brief Read normalized weights through a pointer
    double *read_weight (double *first) const
    {
        const double *const wptr = &weight_[0];
        VSMC_RUNTIME_ASSERT(
                (std::abs(first - wptr) > static_cast<std::ptrdiff_t>(size_)),
                "The destination of **WeightSet::read_weight** is "
                "overlapping with the source.\n"
                "How did you get this address?");
        std::memcpy(first, wptr, sizeof(double) * size_);

        return first + size_;
    }

    /// \brief Read unnormalized logarithm weights through an output iterator
    template <typename OutputIter>
    OutputIter read_log_weight (OutputIter first) const
    {
        return std::copy(log_weight_.begin(), log_weight_.end(), first);
    }

    /// \brief Read unnormalized logarithm weights through a random access
    /// iterator with (possible non-uniform stride)
    template <typename RandomIter>
    RandomIter read_log_weight (RandomIter first, int stride) const
    {
        for (size_type i = 0; i != size_; ++i, first += stride)
            *first = log_weight_[i];

        return first;
    }

    /// \brief Read unnormalized logarithm weights through a pointer
    double *read_log_weight (double *first) const
    {
        const double *const lwptr = &log_weight_[0];
        VSMC_RUNTIME_ASSERT(
                (std::abs(first - lwptr) > static_cast<std::ptrdiff_t>(size_)),
                "The destination of **WeightSet::read_weight** is "
                "overlapping with the source.\n"
                "How did you get this address?");
        std::memcpy(first, lwptr, sizeof(double) * size_);

        return first + size_;
    }

    /// \brief Get the normalized weight of the id'th particle
    double weight (size_type id) const
    {
        return weight_[id];
    }

    /// \brief Get the unnormalized logarithm weight of the id'th particle
    double log_weight (size_type id) const
    {
        return log_weight_[id];
    }

    /// \brief Set normalized weight, unnormalized logarithm weight and ESS
    /// such that each particle has a equal weight
    void set_equal_weight ()
    {
        ess_ = static_cast<double>(size_);
        std::fill(weight_.begin(), weight_.end(), 1.0 / size_);
        std::fill(log_weight_.begin(), log_weight_.end(), 0);
    }

    /// \brief Set normalized weight, unnormalized logarithm weight and ESS by
    /// changing the (possible unnormalized) weights directly through an input
    /// iterator
    template <typename InputIter>
    void set_weight (InputIter first)
    {
        for (size_type i = 0; i != size_; ++i, ++first)
            weight_[i] = *first;
        weight2log_weight();
    }

    /// \brief Set normalized weight, unnormalized logarithm weight and ESS by
    /// changing the (possible unnormalized) weights directly through a random
    /// access iterator with (possible non-uniform) stride
    template <typename RandomIter>
    void set_weight (RandomIter first, int stride)
    {
        for (size_type i = 0; i != size_; ++i, first += stride)
            weight_[i] = *first;
        weight2log_weight();
    }

    /// \brief Set normalized weight, unnormalized logarithm weight and ESS by
    /// changing the (possible unnormalized) weights directly through a pointer
    void set_weight (const double *first)
    {
        double *const wptr = &weight_[0];
        VSMC_RUNTIME_ASSERT(
                (std::abs(first - wptr) > static_cast<std::ptrdiff_t>(size_)),
                "The source of **WeightSet::set_weight** is "
                "overlapping with the destination.\n"
                "How did you get this address?");
        std::memcpy(wptr, first, sizeof(double) * size_);
        weight2log_weight();
    }

    /// \brief Set normalized weight, unnormalized logarithm weight and ESS by
    /// multiply the normalized weight with (possible unnormalized) incremental
    /// weights through an input iterator
    template <typename InputIter>
    void mul_weight (InputIter first)
    {
        for (size_type i = 0; i != size_; ++i, ++first)
            weight_[i] *= *first;
        weight2log_weight();
    }

    /// \brief Set normalized weight, unnormalized logarithm weight and ESS by
    /// multiply the normalized weight with (possible unnormalized) incremental
    /// weights through a random access iterator with (possible non-uniform)
    /// stride
    template <typename RandomIter>
    void mul_weight (RandomIter first, int stride)
    {
        for (size_type i = 0; i != size_; ++i, first += stride)
            weight_[i] *= *first;
        weight2log_weight();
    }

    /// \brief Set normalized weight, unnormalized logarithm weight and ESS by
    /// changing the (possible unnormalized) logarithm weights directly through
    /// an input iterator
    template <typename InputIter>
    void set_log_weight (InputIter first)
    {
        for (size_type i = 0; i != size_; ++i, ++first)
            log_weight_[i] = *first;
        log_weight2weight();
    }

    /// \brief Set normalized weight, unnormalized logarithm weight and ESS by
    /// changing the (possible unnormalized) logarithm weights directly through
    /// a random access iterator with (possible non-uniform) stride
    template <typename RandomIter>
    void set_log_weight (RandomIter first, int stride)
    {
        for (size_type i = 0; i != size_; ++i, first += stride)
            log_weight_[i] = *first;
        log_weight2weight();
    }

    /// \brief Set normalized weight, unnormalized logarithm weight and ESS by
    /// changing the (possible unnormalized) logarithm weights directly through
    /// a pointer
    void set_log_weight (const double *first)
    {
        double *const lwptr = &log_weight_[0];
        VSMC_RUNTIME_ASSERT(
                (std::abs(first - lwptr) > static_cast<std::ptrdiff_t>(size_)),
                "The source of **WeightSet::set_log_weight** is "
                "overlapping with the destination.\n"
                "How did you get this address?");
        std::memcpy(lwptr, first, sizeof(double) * size_);
        log_weight2weight();
    }

    /// \brief Set normalized weight, unnormalized logarithm weight and ESS by
    /// adding to the unnormalized logarithm weights with (possible
    /// unormalized) logarithm incremental weights through an input iterator
    template <typename InputIter>
    void add_log_weight (InputIter first)
    {
        for (size_type i = 0; i != size_; ++i, ++first)
            log_weight_[i] += *first;
        log_weight2weight();
    }

    /// \brief Set normalized weight, unnormalized logarithm weight and ESS by
    /// adding to the unnormalized logarithm weights with (possible
    /// unormalized) logarithm incremental weights through a ranodm access
    /// iterator with (possible non-uniform) stride
    template <typename RandomIter>
    void add_log_weight (RandomIter first, int stride)
    {
        for (size_type i = 0; i != size_; ++i, first += stride)
            log_weight_[i] += *first;
        log_weight2weight();
    }

    /// \brief Get the ESS of the particle collection based on the current
    /// weights
    double ess () const
    {
        return ess_;
    }

    protected :

    set_ess (double new_ess) {ess_ = new_ess;}

    double *weight_ptr     () {return &weight_[0];}
    double *log_weight_ptr () {return &log_weight_[0];}

    const double *weight_ptr     () const {return &weight_[0];}
    const double *log_weight_ptr () const {return &log_weight_[0];}

    private :

    size_type size_;
    double ess_;
    std::vector<double> weight_;
    std::vector<double> log_weight_;
    ddot_type ddot_;

    void log_weight2weight ()
    {
        using std::exp;

        std::vector<double>::const_iterator id_max = std::max_element(
                log_weight_.begin(), log_weight_.end());
        double max_weight = *id_max;
        for (size_type i = 0; i != size_; ++i)
            log_weight_[i] -= max_weight;

        for (size_type i = 0; i != size_; ++i)
            weight_[i] = exp(log_weight_[i]);
        double coeff = std::accumulate(weight_.begin(), weight_.end(),
                static_cast<double>(0));
        coeff = 1 / coeff;
        for (size_type i = 0; i != size_; ++i)
            weight_[i] *= coeff;

        ess_ = 1 / ddot_(static_cast<typename ddot_type::size_type>(size_),
                &weight_[0], 1, &weight_[0], 1);
    }

    void weight2log_weight ()
    {
        using std::log;

        double coeff = std::accumulate(weight_.begin(), weight_.end(),
                static_cast<double>(0));
        coeff = 1 / coeff;
        for (size_type i = 0; i != size_; ++i)
            weight_[i] *= coeff;

        for (size_type i = 0; i != size_; ++i)
            log_weight_[i] = log(weight_[i]);

        ess_ = 1 / ddot_(static_cast<typename ddot_type::size_type>(size_),
                &weight_[0], 1, &weight_[0], 1);
    }
}; // class WeightSet

} // namespace vsmc

VSMC_DEFINE_TYPE_DISPATCH_TRAIT(WeightSetType, weight_set_type, WeightSet<T>);

#endif // VSMC_CORE_WEIGHT_HPP
<commit_msg>fix tests<commit_after>#ifndef VSMC_CORE_WEIGHT_HPP
#define VSMC_CORE_WEIGHT_HPP

#include <vsmc/internal/common.hpp>
#include <vsmc/utility/cxxblas.hpp>

namespace vsmc {

/// \brief Weight set class
/// \ingroup Core
template <typename T>
class WeightSet
{
    public :

    typedef typename traits::SizeTypeTrait<T>::type size_type;
    typedef typename traits::DDotTypeTrait<T>::type ddot_type;

    explicit WeightSet (size_type N) :
        size_(N), ess_(static_cast<double>(N)), weight_(N), log_weight_(N) {}

    size_type resample_size () const
    {
        return size_;
    }

    template <typename OutputIter>
    OutputIter read_resample_weight (OutputIter first) const
    {
        return read_weight(first);
    }

    template <typename RandomIter>
    RandomIter read_resample_weight (RandomIter first, int stride) const
    {
        return read_weight(first, stride);
    }

    /// \brief Read normalized weights through an output iterator
    template <typename OutputIter>
    OutputIter read_weight (OutputIter first) const
    {
        return std::copy(weight_.begin(), weight_.end(), first);
    }

    /// \brief Read normalized weights through a random access iterator with
    /// (possible non-uniform stride)
    template <typename RandomIter>
    RandomIter read_weight (RandomIter first, int stride) const
    {
        for (size_type i = 0; i != size_; ++i, first += stride)
            *first = weight_[i];

        return first;
    }

    /// \brief Read normalized weights through a pointer
    double *read_weight (double *first) const
    {
        const double *const wptr = &weight_[0];
        VSMC_RUNTIME_ASSERT(
                (std::abs(first - wptr) > static_cast<std::ptrdiff_t>(size_)),
                "The destination of **WeightSet::read_weight** is "
                "overlapping with the source.\n"
                "How did you get this address?");
        std::memcpy(first, wptr, sizeof(double) * size_);

        return first + size_;
    }

    /// \brief Read unnormalized logarithm weights through an output iterator
    template <typename OutputIter>
    OutputIter read_log_weight (OutputIter first) const
    {
        return std::copy(log_weight_.begin(), log_weight_.end(), first);
    }

    /// \brief Read unnormalized logarithm weights through a random access
    /// iterator with (possible non-uniform stride)
    template <typename RandomIter>
    RandomIter read_log_weight (RandomIter first, int stride) const
    {
        for (size_type i = 0; i != size_; ++i, first += stride)
            *first = log_weight_[i];

        return first;
    }

    /// \brief Read unnormalized logarithm weights through a pointer
    double *read_log_weight (double *first) const
    {
        const double *const lwptr = &log_weight_[0];
        VSMC_RUNTIME_ASSERT(
                (std::abs(first - lwptr) > static_cast<std::ptrdiff_t>(size_)),
                "The destination of **WeightSet::read_weight** is "
                "overlapping with the source.\n"
                "How did you get this address?");
        std::memcpy(first, lwptr, sizeof(double) * size_);

        return first + size_;
    }

    /// \brief Get the normalized weight of the id'th particle
    double weight (size_type id) const
    {
        return weight_[id];
    }

    /// \brief Get the unnormalized logarithm weight of the id'th particle
    double log_weight (size_type id) const
    {
        return log_weight_[id];
    }

    /// \brief Set normalized weight, unnormalized logarithm weight and ESS
    /// such that each particle has a equal weight
    void set_equal_weight ()
    {
        ess_ = static_cast<double>(size_);
        std::fill(weight_.begin(), weight_.end(), 1.0 / size_);
        std::fill(log_weight_.begin(), log_weight_.end(), 0);
    }

    /// \brief Set normalized weight, unnormalized logarithm weight and ESS by
    /// changing the (possible unnormalized) weights directly through an input
    /// iterator
    template <typename InputIter>
    void set_weight (InputIter first)
    {
        for (size_type i = 0; i != size_; ++i, ++first)
            weight_[i] = *first;
        weight2log_weight();
    }

    /// \brief Set normalized weight, unnormalized logarithm weight and ESS by
    /// changing the (possible unnormalized) weights directly through a random
    /// access iterator with (possible non-uniform) stride
    template <typename RandomIter>
    void set_weight (RandomIter first, int stride)
    {
        for (size_type i = 0; i != size_; ++i, first += stride)
            weight_[i] = *first;
        weight2log_weight();
    }

    /// \brief Set normalized weight, unnormalized logarithm weight and ESS by
    /// changing the (possible unnormalized) weights directly through a pointer
    void set_weight (const double *first)
    {
        double *const wptr = &weight_[0];
        VSMC_RUNTIME_ASSERT(
                (std::abs(first - wptr) > static_cast<std::ptrdiff_t>(size_)),
                "The source of **WeightSet::set_weight** is "
                "overlapping with the destination.\n"
                "How did you get this address?");
        std::memcpy(wptr, first, sizeof(double) * size_);
        weight2log_weight();
    }

    /// \brief Set normalized weight, unnormalized logarithm weight and ESS by
    /// multiply the normalized weight with (possible unnormalized) incremental
    /// weights through an input iterator
    template <typename InputIter>
    void mul_weight (InputIter first)
    {
        for (size_type i = 0; i != size_; ++i, ++first)
            weight_[i] *= *first;
        weight2log_weight();
    }

    /// \brief Set normalized weight, unnormalized logarithm weight and ESS by
    /// multiply the normalized weight with (possible unnormalized) incremental
    /// weights through a random access iterator with (possible non-uniform)
    /// stride
    template <typename RandomIter>
    void mul_weight (RandomIter first, int stride)
    {
        for (size_type i = 0; i != size_; ++i, first += stride)
            weight_[i] *= *first;
        weight2log_weight();
    }

    /// \brief Set normalized weight, unnormalized logarithm weight and ESS by
    /// changing the (possible unnormalized) logarithm weights directly through
    /// an input iterator
    template <typename InputIter>
    void set_log_weight (InputIter first)
    {
        for (size_type i = 0; i != size_; ++i, ++first)
            log_weight_[i] = *first;
        log_weight2weight();
    }

    /// \brief Set normalized weight, unnormalized logarithm weight and ESS by
    /// changing the (possible unnormalized) logarithm weights directly through
    /// a random access iterator with (possible non-uniform) stride
    template <typename RandomIter>
    void set_log_weight (RandomIter first, int stride)
    {
        for (size_type i = 0; i != size_; ++i, first += stride)
            log_weight_[i] = *first;
        log_weight2weight();
    }

    /// \brief Set normalized weight, unnormalized logarithm weight and ESS by
    /// changing the (possible unnormalized) logarithm weights directly through
    /// a pointer
    void set_log_weight (const double *first)
    {
        double *const lwptr = &log_weight_[0];
        VSMC_RUNTIME_ASSERT(
                (std::abs(first - lwptr) > static_cast<std::ptrdiff_t>(size_)),
                "The source of **WeightSet::set_log_weight** is "
                "overlapping with the destination.\n"
                "How did you get this address?");
        std::memcpy(lwptr, first, sizeof(double) * size_);
        log_weight2weight();
    }

    /// \brief Set normalized weight, unnormalized logarithm weight and ESS by
    /// adding to the unnormalized logarithm weights with (possible
    /// unormalized) logarithm incremental weights through an input iterator
    template <typename InputIter>
    void add_log_weight (InputIter first)
    {
        for (size_type i = 0; i != size_; ++i, ++first)
            log_weight_[i] += *first;
        log_weight2weight();
    }

    /// \brief Set normalized weight, unnormalized logarithm weight and ESS by
    /// adding to the unnormalized logarithm weights with (possible
    /// unormalized) logarithm incremental weights through a ranodm access
    /// iterator with (possible non-uniform) stride
    template <typename RandomIter>
    void add_log_weight (RandomIter first, int stride)
    {
        for (size_type i = 0; i != size_; ++i, first += stride)
            log_weight_[i] += *first;
        log_weight2weight();
    }

    /// \brief Get the ESS of the particle collection based on the current
    /// weights
    double ess () const
    {
        return ess_;
    }

    protected :

    void set_ess (double new_ess) {ess_ = new_ess;}

    double *weight_ptr     () {return &weight_[0];}
    double *log_weight_ptr () {return &log_weight_[0];}

    const double *weight_ptr     () const {return &weight_[0];}
    const double *log_weight_ptr () const {return &log_weight_[0];}

    private :

    size_type size_;
    double ess_;
    std::vector<double> weight_;
    std::vector<double> log_weight_;
    ddot_type ddot_;

    void log_weight2weight ()
    {
        using std::exp;

        std::vector<double>::const_iterator id_max = std::max_element(
                log_weight_.begin(), log_weight_.end());
        double max_weight = *id_max;
        for (size_type i = 0; i != size_; ++i)
            log_weight_[i] -= max_weight;

        for (size_type i = 0; i != size_; ++i)
            weight_[i] = exp(log_weight_[i]);
        double coeff = std::accumulate(weight_.begin(), weight_.end(),
                static_cast<double>(0));
        coeff = 1 / coeff;
        for (size_type i = 0; i != size_; ++i)
            weight_[i] *= coeff;

        ess_ = 1 / ddot_(static_cast<typename ddot_type::size_type>(size_),
                &weight_[0], 1, &weight_[0], 1);
    }

    void weight2log_weight ()
    {
        using std::log;

        double coeff = std::accumulate(weight_.begin(), weight_.end(),
                static_cast<double>(0));
        coeff = 1 / coeff;
        for (size_type i = 0; i != size_; ++i)
            weight_[i] *= coeff;

        for (size_type i = 0; i != size_; ++i)
            log_weight_[i] = log(weight_[i]);

        ess_ = 1 / ddot_(static_cast<typename ddot_type::size_type>(size_),
                &weight_[0], 1, &weight_[0], 1);
    }
}; // class WeightSet

} // namespace vsmc

VSMC_DEFINE_TYPE_DISPATCH_TRAIT(WeightSetType, weight_set_type, WeightSet<T>);

#endif // VSMC_CORE_WEIGHT_HPP
<|endoftext|>


<commit_before>/*
 * master.cpp - master program for Team PI
 *
 * Wire(0) -> capTouch -> pixies -> SRF08s -> slave2 -> slave3
 * Wire1   -> slave1
 * by Brian Chen
 * (C) Team PI 2015
 */

#include <WProgram.h>
#include <i2c_t3.h>
#include <SPI.h>
#include <slaves.h>
#include <piCommon.h>
#include <PixyI2C.h>
#include <SRF08.h>
#include <fastTrig.h>
#include <PID.h>

#define LED 13

/**********************************************************/
/*					     Slave1   						  */
/**********************************************************/
union float2bytes { float f; uint8_t b[sizeof(float)]; };
float2bytes f2b;
uint8_t inBuffer[22] = {0};
float bearing;
int32_t bearing_int;

/**********************************************************/
/*                        Orbit                           */
/**********************************************************/
float orbit_k;
int16_t targetDir;
uint8_t targetVelocity;

/**********************************************************/
/*                    Face forwards                       */
/**********************************************************/
#define BEARING_KP 0.6
#define BEARING_KD 0

int32_t targetBearing = 0;
int32_t rotatationCorrection;

PID bearingPID (&bearing_int, &rotatationCorrection, &targetBearing,
	BEARING_KP, 0, BEARING_KD, -255, 255, 1000);

/**********************************************************/
/*                      Backspin                          */
/**********************************************************/
int16_t backspinSpeed = 0;

/**********************************************************/
/*                       Kicker                           */
/**********************************************************/
#define KICK_TIME 4000
#define KICK_DURATION 80

#define KICK_SIG 21
#define KICK_ANA A3

/**********************************************************/
/*					     Camera   						  */
/**********************************************************/
#define PIXY1_ADDRESS 0x54   // default i2c address

#define MIN_BLOCK_AREA   2000
#define MIN_BLOCK_WIDTH  100
#define MIN_BLOCK_HEIGHT 20

PixyI2C pixy1(PIXY1_ADDRESS);

int16_t goalAngle = 0;
uint16_t goalArea = 0;

/**********************************************************/
/*					     Ultrasonics					  */
/**********************************************************/
#define SRF_BACK_ADDRESS  0x70  // 0xE0
#define SRF_RIGHT_ADDRESS 0x71  // 0xE2
#define SRF_LEFT_ADDRESS  0x72  // 0xE4

SRF08 srfBack(SRF_BACK_ADDRESS);
SRF08 srfRight(SRF_RIGHT_ADDRESS);
SRF08 srfLeft(SRF_LEFT_ADDRESS);

int16_t backDistance, rightDistance, leftDistance;

/**********************************************************/
/*					       TSOPS    					  */
/**********************************************************/

uint8_t tsopAngleByte;
int16_t tsopAngle;
int16_t tsopAngle_r_goal; // tsop angle relative to goal
uint8_t tsopStrength;
uint8_t ballDistance;

uint8_t tsopData[24] = {0};

/**********************************************************/
/*					       LASER    					  */
/**********************************************************/
#define LASER_SIG A1
#define LASER_REF 152

bool ballInZone = false;

int32_t ballAngle;

int getOrbit(int angle, int strength){

}

void simpleChase(){
	// for (int i = 0; i < 360; i++){
	// 	Slave3.moveRobot(i, 20, 0);
	// 	delay(20);
	// }
	if (tsopAngleByte != 255){
		Slave3.moveRobot(tsopAngleByte*180/255, 255, 0);
		//Serial.println("move");
	}
	else{
		Slave3.moveRobot(tsopAngleByte*180/255, 0, 0);
		//Serial.println("stop");
	}
}

void calcOrbit(){

}
void simpleOrbit(){

	int angleDeg = tsopAngleByte * 360/255;
	int dir;
	uint8_t speed = 110;
	if (angleDeg >= 180){
		angleDeg -= 360;
	}

	if (tsopStrength > 100){
		// ball detected

		if (abs(angleDeg) <= 15){
			dir = 0;
			speed = 255;
		}
		else if (abs(angleDeg) <= 45){
			dir = angleDeg * 1.3;
		}
		else if (abs(angleDeg) <= 60){
			dir = angleDeg * 1.5;
		}
		else if (abs(angleDeg) <= 120){
			dir = angleDeg * 1.8;
		}
		else{
			dir = angleDeg * 1.2;
		}

		// Serial.print("angleDeg\t");
		// Serial.print(angleDeg);
		// Serial.print("dir\t");
		// Serial.print(dir);
		// Serial.print('\t');
		if (dir < 0){
			dir += 360;
		}
		Serial.print(tsopStrength);
		Serial.println("see ball");
		Slave3.moveRobot(dir*255/360, speed, goalAngle);
		//Serial.println("move");
	}
	else{

		Serial.println(goalAngle);
		Slave3.moveRobot(tsopAngleByte*180/255, 0, goalAngle);
		//Serial.println("stop");
	}
}

int main(void){
	Serial.begin(115200);

	Wire.begin();

	SPI.setSCK(14);
	SPI.begin();

	pinMode(LED, OUTPUT);
	pinMode(LASER_SIG, INPUT);

	pinMode(KICK_SIG, OUTPUT);
	pinMode(KICK_ANA, INPUT);

	digitalWrite(LED, HIGH);

	delay(500);

	Slave1.begin(115200);
	Slave2.begin();
	Slave3.begin();

	while(1){
		/* ultrasonics */

		// srfBack.getRangeIfCan(backDistance);
		// srfRight.getRangeIfCan(rightDistance);
		// srfLeft.getRangeIfCan(leftDistance);
		/* end ultrasonics */

		/* goal detection */
		pixy1.getBlocks();
		goalArea = pixy1.blocks[0].width * pixy1.blocks[0].height;
		if (goalArea > 100
//			&& abs(bearing) < 90
			){
			goalAngle = (pixy1.blocks[0].x - 160) * 75 / 360;
		}
		else{
			goalAngle = 0;
		}
		/* end goal detection */

		/* orientation/imu */
		Slave1.requestPacket(SLAVE1_COMMANDS::REQUEST_STANDARD_PACKET);
		Slave1.receivePacket(inBuffer, 7, true);

		f2b.b[0] = inBuffer[2];
		f2b.b[1] = inBuffer[3];
		f2b.b[2] = inBuffer[4];
		f2b.b[3] = inBuffer[5];
		bearing = -f2b.f;
		bearing_int = (int32_t)bearing;

		/* end orientation/imu */

		/* tsops */
		tsopAngleByte = Slave2.getTSOP_ANGLE_BYTE();
		delayMicroseconds(50);
		tsopStrength = Slave2.getTSOP_STRENGTH();
		//Slave2.getTSOPAngleStrength(tsopAngleByte, tsopStrength);

		ballDistance = 180 - tsopStrength;

		tsopAngle = tsopAngleByte * 360/255;
		TOBEARING180(tsopAngle);
		tsopAngle_r_goal = tsopAngle - goalAngle;
		TOBEARING180(tsopAngle_r_goal);

		/* end tsops */

		/* ball in zone */
		if (analogRead(LASER_SIG) < LASER_REF
		 && abs(tsopAngle) < 30
		 && tsopStrength > 150){
			ballInZone = true;
		}
		else{
			ballInZone = false;
		}
		/* end ball in zone */

		/* face forwards */
		bearingPID.update();
		/* end face forwards */

		/*movement control*/

		targetVelocity = 130;

		orbit_k = 1;

		if (tsopStrength > 156){
			orbit_k = 1.1;
		}
		else if (tsopStrength > 150){
			orbit_k = 1.05;
		}
		else if (tsopStrength > 140){
			orbit_k = 1.0;
		}
		else if (tsopStrength > 130){
			orbit_k = 1.0;
		}
		else if (tsopStrength > 120){
			orbit_k = 1;
		}
		else if (tsopStrength > 100){
			orbit_k = 1;
		}
		else if (tsopStrength > 70){
			orbit_k = 1;
		}
		else{
			targetVelocity = 0;
		}

		// if (tsopAngle > 90){
		// 	targetDir = (orbit_k * 180 - 90 + tsopAngle);
		// }
		// else if (tsopAngle < -90){
		// 	targetDir = (orbit_k * -180 + 90 + tsopAngle);
		// }
		// else{
			targetDir = orbit_k * (270 - abs(tsopAngle)) / 90 * tsopAngle;
		// }

		if (ballInZone && abs(goalAngle) < 10){
			// GO!
			targetDir = goalAngle;
			targetVelocity = 200;
		}

		if (targetDir < 0) targetDir += 360;
		targetDir = targetDir * 255/360;

		/* end movement control */

		/* backspin control */
		if (tsopStrength > 70){
			if (abs(targetDir) < 60){
				if (ballInZone){
					// we're going forwards and we have the ball
					// no need for too much spin
					backspinSpeed = 0;
				}
				else{
					// forwards but ball not here yet!
					backspinSpeed = 120;
				}
			}
			else{
				if (ballInZone){
					// we're not going forwards but we have the ball
					// best to spin a bit more as we need to guide the ball more
					backspinSpeed = 150;
				}
				else{
					// most common. Should only spin when ball is in front
					if (abs(tsopAngle) < 60){
						backspinSpeed = 255;
					}
					else{
						// no chance of getting ball any time soon
						backspinSpeed = 0;
					}
				}
			}
		}
		else{
			// no ball detected!
			backspinSpeed = 0;
		}

		/* end backspin control */

		Slave3.moveRobot((uint8_t)targetDir, targetVelocity, rotatationCorrection);
		Slave3.moveMotorE(backspinSpeed);

		/* debugging */
		Serial.printf("%d\t%d\t\t%d\t%.1f\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\n",
					  micros(),
					  goalAngle,
					  goalArea,
					  bearing,
					  backDistance,
					  rightDistance,
					  leftDistance,
					  tsopAngle,
					  ballDistance,
					  ballInZone,
					  targetDir,
					  targetVelocity,
					  rotatationCorrection);
		/* end debugging */
	}
}<commit_msg>implemented bearing offset<commit_after>/*
 * master.cpp - master program for Team PI
 *
 * Wire(0) -> capTouch -> pixies -> SRF08s -> slave2 -> slave3
 * Wire1   -> slave1
 * by Brian Chen
 * (C) Team PI 2015
 */

#include <WProgram.h>
#include <i2c_t3.h>
#include <SPI.h>
#include <slaves.h>
#include <piCommon.h>
#include <PixyI2C.h>
#include <SRF08.h>
#include <fastTrig.h>
#include <PID.h>

#define LED 13

/**********************************************************/
/*					     Slave1   						  */
/**********************************************************/
union float2bytes { float f; uint8_t b[sizeof(float)]; };
float2bytes f2b;
uint8_t inBuffer[22] = {0};
float bearing;
float bearing_offset;
int32_t bearing_int;

/**********************************************************/
/*                        Orbit                           */
/**********************************************************/
float orbit_k;
int16_t targetDir;
uint8_t targetVelocity;

/**********************************************************/
/*                    Face forwards                       */
/**********************************************************/
#define BEARING_KP 0.6
#define BEARING_KD 0

int32_t targetBearing = 0;
int32_t rotatationCorrection;

PID bearingPID (&bearing_int, &rotatationCorrection, &targetBearing,
	BEARING_KP, 0, BEARING_KD, -255, 255, 1000);

/**********************************************************/
/*                      Backspin                          */
/**********************************************************/
int16_t backspinSpeed = 0;

/**********************************************************/
/*                       Kicker                           */
/**********************************************************/
#define KICK_TIME 4000
#define KICK_DURATION 80

#define KICK_SIG 21
#define KICK_ANA A3

/**********************************************************/
/*					     Camera   						  */
/**********************************************************/
#define PIXY1_ADDRESS 0x54   // default i2c address

#define MIN_BLOCK_AREA   2000
#define MIN_BLOCK_WIDTH  100
#define MIN_BLOCK_HEIGHT 20

PixyI2C pixy1(PIXY1_ADDRESS);

int16_t goalAngle = 0;
uint16_t goalArea = 0;

/**********************************************************/
/*					     Ultrasonics					  */
/**********************************************************/
#define SRF_BACK_ADDRESS  0x70  // 0xE0
#define SRF_RIGHT_ADDRESS 0x71  // 0xE2
#define SRF_LEFT_ADDRESS  0x72  // 0xE4

SRF08 srfBack(SRF_BACK_ADDRESS);
SRF08 srfRight(SRF_RIGHT_ADDRESS);
SRF08 srfLeft(SRF_LEFT_ADDRESS);

int16_t backDistance, rightDistance, leftDistance;

/**********************************************************/
/*					       TSOPS    					  */
/**********************************************************/

uint8_t tsopAngleByte;
int16_t tsopAngle;
int16_t tsopAngle_r_goal; // tsop angle relative to goal
uint8_t tsopStrength;
uint8_t ballDistance;

uint8_t tsopData[24] = {0};

/**********************************************************/
/*					       LASER    					  */
/**********************************************************/
#define LASER_SIG A1
#define LASER_REF 152

bool ballInZone = false;

void calibIMUOffset(){
	for (int i = 0; i < 50; i++){
		Slave1.requestPacket(SLAVE1_COMMANDS::REQUEST_STANDARD_PACKET);
		Slave1.receivePacket(inBuffer, 7, true);

		f2b.b[0] = inBuffer[2];
		f2b.b[1] = inBuffer[3];
		f2b.b[2] = inBuffer[4];
		f2b.b[3] = inBuffer[5];
		bearing_offset += -f2b.f;
		delay(1);
	}
	bearing_offset /= 50;
	while(!Serial.available()){};
	Serial.println(bearing_offset);
	delay(2000);
}

int main(void){
	Serial.begin(115200);

	Wire.begin();

	SPI.setSCK(14);
	SPI.begin();

	Slave1.begin(115200);
	Slave2.begin();
	Slave3.begin();

	pinMode(LED, OUTPUT);
	pinMode(LASER_SIG, INPUT);

	pinMode(KICK_SIG, OUTPUT);
	pinMode(KICK_ANA, INPUT);

	digitalWrite(LED, HIGH);

	delay(1000);

	calibIMUOffset();

	while(1){
		/* ultrasonics */

		// srfBack.getRangeIfCan(backDistance);
		// srfRight.getRangeIfCan(rightDistance);
		// srfLeft.getRangeIfCan(leftDistance);
		/* end ultrasonics */

		/* goal detection */
		pixy1.getBlocks();
		goalArea = pixy1.blocks[0].width * pixy1.blocks[0].height;
		if (goalArea > 100
//			&& abs(bearing) < 90
			){
			goalAngle = (pixy1.blocks[0].x - 160) * 75 / 360;
		}
		else{
			goalAngle = 0;
		}
		/* end goal detection */

		/* orientation/imu */
		Slave1.requestPacket(SLAVE1_COMMANDS::REQUEST_STANDARD_PACKET);
		Slave1.receivePacket(inBuffer, 7, true);

		f2b.b[0] = inBuffer[2];
		f2b.b[1] = inBuffer[3];
		f2b.b[2] = inBuffer[4];
		f2b.b[3] = inBuffer[5];
		bearing = -f2b.f - bearing_offset;
		bearing_int = round(bearing);
		TOBEARING180(bearing_int);
		TOBEARING180(bearing);

		/* end orientation/imu */

		/* tsops */
		tsopAngleByte = Slave2.getTSOP_ANGLE_BYTE();
		delayMicroseconds(50);
		tsopStrength = Slave2.getTSOP_STRENGTH();
		//Slave2.getTSOPAngleStrength(tsopAngleByte, tsopStrength);

		ballDistance = 180 - tsopStrength;

		tsopAngle = tsopAngleByte * 360/255;
		TOBEARING180(tsopAngle);
		tsopAngle_r_goal = tsopAngle - goalAngle;
		TOBEARING180(tsopAngle_r_goal);

		/* end tsops */

		/* ball in zone */
		if (analogRead(LASER_SIG) < LASER_REF
		 && abs(tsopAngle) < 30
		 && tsopStrength > 150){
			ballInZone = true;
		}
		else{
			ballInZone = false;
		}
		/* end ball in zone */

		/* face forwards */
		bearingPID.update();
		/* end face forwards */

		/*movement control*/

		targetVelocity = 130;

		orbit_k = 1;

		if (tsopStrength > 156){
			orbit_k = 1.1;
		}
		else if (tsopStrength > 150){
			orbit_k = 1.05;
		}
		else if (tsopStrength > 140){
			orbit_k = 1.0;
		}
		else if (tsopStrength > 130){
			orbit_k = 1.0;
		}
		else if (tsopStrength > 120){
			orbit_k = 1;
		}
		else if (tsopStrength > 100){
			orbit_k = 1;
		}
		else if (tsopStrength > 70){
			orbit_k = 1;
		}
		else{
			targetVelocity = 0;
		}

		// if (tsopAngle > 90){
		// 	targetDir = (orbit_k * 180 - 90 + tsopAngle);
		// }
		// else if (tsopAngle < -90){
		// 	targetDir = (orbit_k * -180 + 90 + tsopAngle);
		// }
		// else{
			targetDir = orbit_k * (270 - abs(tsopAngle)) / 90 * tsopAngle;
		// }

		if (ballInZone && abs(goalAngle) < 10){
			// GO!
			targetDir = goalAngle;
			targetVelocity = 200;
		}

		if (targetDir < 0) targetDir += 360;
		targetDir = targetDir * 255/360;

		/* end movement control */

		/* backspin control */
		if (tsopStrength > 70){
			if (abs(targetDir) < 60){
				if (ballInZone){
					// we're going forwards and we have the ball
					// no need for too much spin
					backspinSpeed = 0;
				}
				else{
					// forwards but ball not here yet!
					backspinSpeed = 120;
				}
			}
			else{
				if (ballInZone){
					// we're not going forwards but we have the ball
					// best to spin a bit more as we need to guide the ball more
					backspinSpeed = 150;
				}
				else{
					// most common. Should only spin when ball is in front
					if (abs(tsopAngle) < 60){
						backspinSpeed = 255;
					}
					else{
						// no chance of getting ball any time soon
						backspinSpeed = 0;
					}
				}
			}
		}
		else{
			// no ball detected!
			backspinSpeed = 0;
		}

		/* end backspin control */

		Slave3.moveRobot((uint8_t)targetDir, targetVelocity, rotatationCorrection);
		Slave3.moveMotorE(backspinSpeed);

		/* debugging */
		Serial.printf("%d\t%d\t\t%d\t%.1f\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\n",
					  micros(),
					  goalAngle,
					  goalArea,
					  bearing,
					  backDistance,
					  rightDistance,
					  leftDistance,
					  tsopAngle,
					  ballDistance,
					  ballInZone,
					  targetDir,
					  targetVelocity,
					  rotatationCorrection);
		/* end debugging */
	}
}<|endoftext|>


<commit_before>/********************************************************************************
 *   Copyright (C) 2017 by Bogdan Kozyrev <t800@kvkozyrev.org>                  *
 *   All rights reserved.                                                       *
 *                                                                              *
 *   Part of the Desert Engine Project:                                         *
 *   https://github.com/t800danya/desert-engine/                                *
 *                                                                              *
 *   Redistribution and use in source and binary forms, with or without         *
 *   modification, are permitted provided that the following conditions         *
 *   are met:                                                                   *
 *   - Redistributions may not be sold, nor may they be used in a               *
 *     commercial product or activity.                                          *
 *   - Redistributions of source code and/or in binary form must reproduce      *
 *     the above copyright notice, this list of conditions and the              *
 *     following disclaimer in the documentation and/or other materials         *
 *     provided with the distribution.                                          *
 *                                                                              *
 * THIS SOFTWARE IS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,   *
 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS    *
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT     *
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,        *
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;  *
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,     *
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE         *
 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,            *
 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.                           *
 *******************************************************************************/

#include "arctic_platform_def.h"

#ifdef DESERT_PLATFORM_LINUX

// Примечание от t800: Контрибуты складывать СЮДА! :-)

#endif //DESERT_PLATFORM_LINUX

<commit_msg>Update desert_platform_linux.cpp<commit_after>/********************************************************************************
 *   Copyright (C) 2017 by Bogdan Kozyrev <t800@kvkozyrev.org>                  *
 *   All rights reserved.                                                       *
 *                                                                              *
 *   Part of the Desert Engine Project:                                         *
 *   https://github.com/t800danya/desert-engine/                                *
 *                                                                              *
 *   Redistribution and use in source and binary forms, with or without         *
 *   modification, are permitted provided that the following conditions         *
 *   are met:                                                                   *
 *   - Redistributions may not be sold, nor may they be used in a               *
 *     commercial product or activity.                                          *
 *   - Redistributions of source code and/or in binary form must reproduce      *
 *     the above copyright notice, this list of conditions and the              *
 *     following disclaimer in the documentation and/or other materials         *
 *     provided with the distribution.                                          *
 *                                                                              *
 * THIS SOFTWARE IS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,   *
 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS    *
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT     *
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,        *
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;  *
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,     *
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE         *
 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,            *
 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.                           *
 *******************************************************************************/

#include "arctic_platform_def.h"

#ifdef DESERT_PLATFORM_LINUX

// Примечание от t800: Контрибуты складывать СЮДА! :-)

#endif //DESERT_PLATFORM_LINUX

<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: RangeSelectionHelper.cxx,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change: $Author: vg $ $Date: 2007-05-22 17:29:07 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library 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
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_chart2.hxx"

#include "RangeSelectionHelper.hxx"
#include "RangeSelectionListener.hxx"
#include "macros.hxx"
#include "ControllerLockGuard.hxx"

#ifndef _COM_SUN_STAR_FRAME_XMODEL_HPP_
#include <com/sun/star/frame/XModel.hpp>
#endif
#ifndef _COM_SUN_STAR_AWT_XTOPWINDOW_HPP_
#include <com/sun/star/awt/XTopWindow.hpp>
#endif
#ifndef _COM_SUN_STAR_TEXT_XTEXT_HPP_
#include <com/sun/star/text/XText.hpp>
#endif
#ifndef _COM_SUN_STAR_EMBED_XEMBEDDEDOBJECT_HPP_
#include <com/sun/star/embed/XEmbeddedObject.hpp>
#endif
#ifndef _COM_SUN_STAR_EMBED_EMBEDSTATES_HPP_
#include <com/sun/star/embed/EmbedStates.hpp>
#endif
#ifndef _COM_SUN_STAR_EMBED_XCOMPONENTSUPPLIER_HPP_
#include <com/sun/star/embed/XComponentSupplier.hpp>
#endif
#ifndef _COM_SUN_STAR_SHEET_XCELLRANGEADDRESSABLE_HPP_
#include <com/sun/star/sheet/XCellRangeAddressable.hpp>
#endif
#ifndef _COM_SUN_STAR_SHEET_XSPREADSHEETDOCUMENT_HPP_
#include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
#endif
#ifndef _COM_SUN_STAR_SHEET_XCELLRANGESACCESS_HPP_
#include <com/sun/star/sheet/XCellRangesAccess.hpp>
#endif
#ifndef _COM_SUN_STAR_CHART2_DATA_XRANGEXMLCONVERSION_HPP_
#include <com/sun/star/chart2/data/XRangeXMLConversion.hpp>
#endif

#ifndef _RTL_USTRBUF_HXX_
#include <rtl/ustrbuf.hxx>
#endif

using namespace ::com::sun::star;

using ::com::sun::star::uno::Reference;
using ::com::sun::star::uno::Sequence;
using ::rtl::OUString;

// ----------------------------------------

namespace
{
OUString lcl_getTextFromRanges( const Sequence < Reference< table::XCellRange > >& xRanges )
{
    ::rtl::OUStringBuffer aResultBuf;

    try
    {
        sal_Int32 nCount(xRanges.getLength());
        for (sal_Int32 i = 0; i < nCount; ++i)
        {
            Reference< sheet::XCellRangeAddressable > xAddressable( xRanges[i], uno::UNO_QUERY );
            if( xAddressable.is())
            {
                // iterate through columns first
                table::CellRangeAddress aAddr = xAddressable->getRangeAddress();
                bool bInsSpace = false;
                for( sal_Int32 nCol=aAddr.StartColumn; nCol<=aAddr.EndColumn; ++nCol )
                    for( sal_Int32 nRow=aAddr.StartRow; nRow<=aAddr.EndRow; ++nRow )
                    {
                        if( bInsSpace )
                            aResultBuf.append( sal_Unicode( ' ' ));
                        else
                            bInsSpace = true;
                        Reference< text::XText > xText( xRanges[i]->getCellByPosition(
                                                            nCol - aAddr.StartColumn,
                                                            nRow - aAddr.StartRow ), uno::UNO_QUERY );
                        if( xText.is())
                            aResultBuf.append( xText->getString());
                    }
            }
            else if (xRanges[i].is())
            {
                // assert that (0,0) is valid.  Otherwise an exception is thrown
                Reference< text::XText > xText( xRanges[i]->getCellByPosition( 0, 0 ), uno::UNO_QUERY );
                if( xText.is() )
                    aResultBuf.append( xText->getString());
            }
        }
    }
    catch( uno::Exception & ex )
    {
        ASSERT_EXCEPTION( ex );
    }

    return aResultBuf.makeStringAndClear();
}
} // anonymous namespace

// ----------------------------------------

namespace chart
{

RangeSelectionHelper::RangeSelectionHelper(
    const Reference< chart2::XChartDocument > & xChartDocument ) :
        m_xChartDocument( xChartDocument )
{}

RangeSelectionHelper::~RangeSelectionHelper()
{}

bool RangeSelectionHelper::hasRangeSelection()
{
    return getRangeSelection().is();
}

Reference< sheet::XRangeSelection > RangeSelectionHelper::getRangeSelection()
{
    if( !m_xRangeSelection.is() &&
        m_xChartDocument.is() )
    {
        try
        {
            Reference< chart2::data::XDataProvider > xDataProvider( m_xChartDocument->getDataProvider());
            if( xDataProvider.is())
                m_xRangeSelection.set( xDataProvider->getRangeSelection());
        }
        catch( uno::Exception & ex )
        {
            ASSERT_EXCEPTION( ex );

            m_xRangeSelection.clear();
        }
    }

    return m_xRangeSelection;
}

Reference< sheet::XCellRangesAccess > RangeSelectionHelper::getCellRangesAccess()
{
    if( ! m_xCellRangesAccess.is() &&
        m_xChartDocument.is())
    {
        try
        {
            Reference< sheet::XSpreadsheetDocument > xSpreadDoc;

            // try controller
            Reference< chart2::data::XDataProvider > xDataProvider( m_xChartDocument->getDataProvider());
            if( xDataProvider.is())
            {
                Reference< frame::XController > xCtrl( xDataProvider->getRangeSelection(), uno::UNO_QUERY );

                if( xCtrl.is() )
                    xSpreadDoc.set( xCtrl->getModel(), uno::UNO_QUERY_THROW );
            }

            if( xSpreadDoc.is() )
                m_xCellRangesAccess.set( xSpreadDoc->getSheets(), uno::UNO_QUERY );
        }
        catch( uno::Exception & ex )
        {
            ASSERT_EXCEPTION( ex );
        }
    }

    return m_xCellRangesAccess;
}

void RangeSelectionHelper::raiseRangeSelectionDocument()
{
    Reference< sheet::XRangeSelection > xRangeSel( getRangeSelection());
    if( xRangeSel.is())
    {
        try
        {
            // bring document to front
            Reference< frame::XController > xCtrl( xRangeSel, uno::UNO_QUERY );
            if( xCtrl.is())
            {
                Reference< frame::XFrame > xFrame( xCtrl->getFrame());
                if( xFrame.is())
                {
                    Reference< awt::XTopWindow > xWin( xFrame->getContainerWindow(),
                                                       uno::UNO_QUERY_THROW );
                    xWin->toFront();
                }
            }
        }
        catch( uno::Exception & ex )
        {
            ASSERT_EXCEPTION( ex );
        }
    }
}

bool RangeSelectionHelper::chooseRange(
    const OUString & aCurrentRange,
    const OUString & aUIString,
    RangeSelectionListenerParent & rListenerParent )
{
    ControllerLockGuard aGuard( Reference< frame::XModel >(m_xChartDocument, uno::UNO_QUERY ) );

    bool bResult = true;
    raiseRangeSelectionDocument();

    try
    {
        Reference< sheet::XRangeSelection > xRangeSel( getRangeSelection());
        if( xRangeSel.is())
        {
            Sequence< beans::PropertyValue > aArgs( 4 );
            aArgs[0] = beans::PropertyValue(
                C2U("InitialValue"), -1, uno::makeAny( aCurrentRange ),
                beans::PropertyState_DIRECT_VALUE );
            aArgs[1] = beans::PropertyValue(
                C2U("Title"), -1,
                uno::makeAny( aUIString ),
                beans::PropertyState_DIRECT_VALUE );
            aArgs[2] = beans::PropertyValue(
                C2U("CloseOnMouseRelease"), -1, uno::makeAny( true ),
                beans::PropertyState_DIRECT_VALUE );
            aArgs[3] = beans::PropertyValue(
                C2U("MultiSelectionMode"), -1, uno::makeAny( true ),
                beans::PropertyState_DIRECT_VALUE );

            if( m_xRangeSelectionListener.is() )
                stopRangeListening();
            m_xRangeSelectionListener.set( Reference< sheet::XRangeSelectionListener >(
                new RangeSelectionListener( rListenerParent, aCurrentRange, Reference< frame::XModel >(m_xChartDocument, uno::UNO_QUERY ) )));

            xRangeSel->addRangeSelectionListener( m_xRangeSelectionListener );
            xRangeSel->startRangeSelection( aArgs );
        }
    }
    catch( uno::Exception & ex )
    {
        bResult = false;
        ASSERT_EXCEPTION( ex );
    }

    return bResult;
}

void RangeSelectionHelper::stopRangeListening( bool bRemoveListener /* = true */ )
{
    if( bRemoveListener &&
        m_xRangeSelectionListener.is() &&
        m_xRangeSelection.is() )
    {
        m_xRangeSelection->removeRangeSelectionListener( m_xRangeSelectionListener );
    }

    m_xRangeSelectionListener = 0;
}

bool RangeSelectionHelper::verifyCellRange( const OUString & rRangeStr )
{
    Reference< chart2::data::XDataProvider > xDataProvider( m_xChartDocument->getDataProvider());
    if( ! xDataProvider.is())
        return false;

    bool bResult = false;

    // 1. check if range is valid by converting it to XML format
    Reference< chart2::data::XRangeXMLConversion > xConversion( xDataProvider, uno::UNO_QUERY );
    if( xConversion.is())
    {
        try
        {
            xConversion->convertRangeToXML( rRangeStr );
            bResult = true;
        }
        catch( const uno::Exception & ex )
        {
            bResult = false;
        }
    }
    else
    {
        // 2. check via the XCellRangesAccess interface
        Reference< sheet::XCellRangesAccess > xRangesAccess( getCellRangesAccess());
        if( xRangesAccess.is() )
        {
            // @todo: the interface should provide a method to determine if a cell
            // range is correct, rather than waiting for an exception
            try
            {
                xRangesAccess->getCellRangesByName( rRangeStr );
                bResult = true;
            }
            catch( const uno::Exception & )
            {
                bResult = false;
            }
        }
        else
        {
            // 3. check via createDataSequenceByRangeRepresentation. Note, that
            // this may only work for "simple" ranges (in Writer)
            try
            {
                // if creation fails, we get an exception
                xDataProvider->createDataSequenceByRangeRepresentation( rRangeStr );
                bResult = true;
            }
            catch( const uno::Exception & ex )
            {
                bResult = false;
            }
        }
    }

    return bResult;
}

OUString RangeSelectionHelper::getCellRangeContent( const OUString & rRangeStr )
{
    OUString aResult;

    Reference< sheet::XCellRangesAccess > xRangesAccess( getCellRangesAccess());
    if( xRangesAccess.is())
    {
        // @todo: the interface should provide a method to determine if a cell
        // range is correct, rather than waiting for an exception
        try
        {
            aResult = lcl_getTextFromRanges( xRangesAccess->getCellRangesByName( rRangeStr ) );
        }
        catch( uno::Exception )
        {
        }
    }

    return aResult;
}

} //  namespace chart
<commit_msg>INTEGRATION: CWS chart07 (1.2.12); FILE MERGED 2007/07/10 11:57:28 bm 1.2.12.2: #i69281# warnings removed 2007/06/28 06:15:29 bm 1.2.12.1: use new XDataProvider interfaces for checking validity of ranges<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: RangeSelectionHelper.cxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: rt $ $Date: 2007-07-25 08:31:20 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library 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
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_chart2.hxx"

#include "RangeSelectionHelper.hxx"
#include "RangeSelectionListener.hxx"
#include "macros.hxx"
#include "ControllerLockGuard.hxx"

#ifndef _COM_SUN_STAR_FRAME_XMODEL_HPP_
#include <com/sun/star/frame/XModel.hpp>
#endif
#ifndef _COM_SUN_STAR_AWT_XTOPWINDOW_HPP_
#include <com/sun/star/awt/XTopWindow.hpp>
#endif
#ifndef _COM_SUN_STAR_TEXT_XTEXT_HPP_
#include <com/sun/star/text/XText.hpp>
#endif
#ifndef _COM_SUN_STAR_EMBED_XEMBEDDEDOBJECT_HPP_
#include <com/sun/star/embed/XEmbeddedObject.hpp>
#endif
#ifndef _COM_SUN_STAR_EMBED_EMBEDSTATES_HPP_
#include <com/sun/star/embed/EmbedStates.hpp>
#endif
#ifndef _COM_SUN_STAR_EMBED_XCOMPONENTSUPPLIER_HPP_
#include <com/sun/star/embed/XComponentSupplier.hpp>
#endif
#ifndef _COM_SUN_STAR_SHEET_XCELLRANGEADDRESSABLE_HPP_
#include <com/sun/star/sheet/XCellRangeAddressable.hpp>
#endif
#ifndef _COM_SUN_STAR_SHEET_XSPREADSHEETDOCUMENT_HPP_
#include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
#endif
#ifndef _COM_SUN_STAR_SHEET_XCELLRANGESACCESS_HPP_
#include <com/sun/star/sheet/XCellRangesAccess.hpp>
#endif
#ifndef _COM_SUN_STAR_CHART2_DATA_XRANGEXMLCONVERSION_HPP_
#include <com/sun/star/chart2/data/XRangeXMLConversion.hpp>
#endif

#ifndef _RTL_USTRBUF_HXX_
#include <rtl/ustrbuf.hxx>
#endif

using namespace ::com::sun::star;

using ::com::sun::star::uno::Reference;
using ::com::sun::star::uno::Sequence;
using ::rtl::OUString;

// ----------------------------------------

namespace
{
OUString lcl_getTextFromRanges( const Sequence < Reference< table::XCellRange > >& xRanges )
{
    ::rtl::OUStringBuffer aResultBuf;

    try
    {
        sal_Int32 nCount(xRanges.getLength());
        for (sal_Int32 i = 0; i < nCount; ++i)
        {
            Reference< sheet::XCellRangeAddressable > xAddressable( xRanges[i], uno::UNO_QUERY );
            if( xAddressable.is())
            {
                // iterate through columns first
                table::CellRangeAddress aAddr = xAddressable->getRangeAddress();
                bool bInsSpace = false;
                for( sal_Int32 nCol=aAddr.StartColumn; nCol<=aAddr.EndColumn; ++nCol )
                    for( sal_Int32 nRow=aAddr.StartRow; nRow<=aAddr.EndRow; ++nRow )
                    {
                        if( bInsSpace )
                            aResultBuf.append( sal_Unicode( ' ' ));
                        else
                            bInsSpace = true;
                        Reference< text::XText > xText( xRanges[i]->getCellByPosition(
                                                            nCol - aAddr.StartColumn,
                                                            nRow - aAddr.StartRow ), uno::UNO_QUERY );
                        if( xText.is())
                            aResultBuf.append( xText->getString());
                    }
            }
            else if (xRanges[i].is())
            {
                // assert that (0,0) is valid.  Otherwise an exception is thrown
                Reference< text::XText > xText( xRanges[i]->getCellByPosition( 0, 0 ), uno::UNO_QUERY );
                if( xText.is() )
                    aResultBuf.append( xText->getString());
            }
        }
    }
    catch( uno::Exception & ex )
    {
        ASSERT_EXCEPTION( ex );
    }

    return aResultBuf.makeStringAndClear();
}
} // anonymous namespace

// ----------------------------------------

namespace chart
{

RangeSelectionHelper::RangeSelectionHelper(
    const Reference< chart2::XChartDocument > & xChartDocument ) :
        m_xChartDocument( xChartDocument )
{}

RangeSelectionHelper::~RangeSelectionHelper()
{}

bool RangeSelectionHelper::hasRangeSelection()
{
    return getRangeSelection().is();
}

Reference< sheet::XRangeSelection > RangeSelectionHelper::getRangeSelection()
{
    if( !m_xRangeSelection.is() &&
        m_xChartDocument.is() )
    {
        try
        {
            Reference< chart2::data::XDataProvider > xDataProvider( m_xChartDocument->getDataProvider());
            if( xDataProvider.is())
                m_xRangeSelection.set( xDataProvider->getRangeSelection());
        }
        catch( uno::Exception & ex )
        {
            ASSERT_EXCEPTION( ex );

            m_xRangeSelection.clear();
        }
    }

    return m_xRangeSelection;
}

Reference< sheet::XCellRangesAccess > RangeSelectionHelper::getCellRangesAccess()
{
    if( ! m_xCellRangesAccess.is() &&
        m_xChartDocument.is())
    {
        try
        {
            Reference< sheet::XSpreadsheetDocument > xSpreadDoc;

            // try controller
            Reference< chart2::data::XDataProvider > xDataProvider( m_xChartDocument->getDataProvider());
            if( xDataProvider.is())
            {
                Reference< frame::XController > xCtrl( xDataProvider->getRangeSelection(), uno::UNO_QUERY );

                if( xCtrl.is() )
                    xSpreadDoc.set( xCtrl->getModel(), uno::UNO_QUERY_THROW );
            }

            if( xSpreadDoc.is() )
                m_xCellRangesAccess.set( xSpreadDoc->getSheets(), uno::UNO_QUERY );
        }
        catch( uno::Exception & ex )
        {
            ASSERT_EXCEPTION( ex );
        }
    }

    return m_xCellRangesAccess;
}

void RangeSelectionHelper::raiseRangeSelectionDocument()
{
    Reference< sheet::XRangeSelection > xRangeSel( getRangeSelection());
    if( xRangeSel.is())
    {
        try
        {
            // bring document to front
            Reference< frame::XController > xCtrl( xRangeSel, uno::UNO_QUERY );
            if( xCtrl.is())
            {
                Reference< frame::XFrame > xFrame( xCtrl->getFrame());
                if( xFrame.is())
                {
                    Reference< awt::XTopWindow > xWin( xFrame->getContainerWindow(),
                                                       uno::UNO_QUERY_THROW );
                    xWin->toFront();
                }
            }
        }
        catch( uno::Exception & ex )
        {
            ASSERT_EXCEPTION( ex );
        }
    }
}

bool RangeSelectionHelper::chooseRange(
    const OUString & aCurrentRange,
    const OUString & aUIString,
    RangeSelectionListenerParent & rListenerParent )
{
    ControllerLockGuard aGuard( Reference< frame::XModel >(m_xChartDocument, uno::UNO_QUERY ) );

    bool bResult = true;
    raiseRangeSelectionDocument();

    try
    {
        Reference< sheet::XRangeSelection > xRangeSel( getRangeSelection());
        if( xRangeSel.is())
        {
            Sequence< beans::PropertyValue > aArgs( 4 );
            aArgs[0] = beans::PropertyValue(
                C2U("InitialValue"), -1, uno::makeAny( aCurrentRange ),
                beans::PropertyState_DIRECT_VALUE );
            aArgs[1] = beans::PropertyValue(
                C2U("Title"), -1,
                uno::makeAny( aUIString ),
                beans::PropertyState_DIRECT_VALUE );
            aArgs[2] = beans::PropertyValue(
                C2U("CloseOnMouseRelease"), -1, uno::makeAny( true ),
                beans::PropertyState_DIRECT_VALUE );
            aArgs[3] = beans::PropertyValue(
                C2U("MultiSelectionMode"), -1, uno::makeAny( true ),
                beans::PropertyState_DIRECT_VALUE );

            if( m_xRangeSelectionListener.is() )
                stopRangeListening();
            m_xRangeSelectionListener.set( Reference< sheet::XRangeSelectionListener >(
                new RangeSelectionListener( rListenerParent, aCurrentRange, Reference< frame::XModel >(m_xChartDocument, uno::UNO_QUERY ) )));

            xRangeSel->addRangeSelectionListener( m_xRangeSelectionListener );
            xRangeSel->startRangeSelection( aArgs );
        }
    }
    catch( uno::Exception & ex )
    {
        bResult = false;
        ASSERT_EXCEPTION( ex );
    }

    return bResult;
}

void RangeSelectionHelper::stopRangeListening( bool bRemoveListener /* = true */ )
{
    if( bRemoveListener &&
        m_xRangeSelectionListener.is() &&
        m_xRangeSelection.is() )
    {
        m_xRangeSelection->removeRangeSelectionListener( m_xRangeSelectionListener );
    }

    m_xRangeSelectionListener = 0;
}

bool RangeSelectionHelper::verifyCellRange( const OUString & rRangeStr )
{
    Reference< chart2::data::XDataProvider > xDataProvider( m_xChartDocument->getDataProvider());
    if( ! xDataProvider.is())
        return false;

    return xDataProvider->createDataSequenceByRangeRepresentationPossible( rRangeStr );
}

bool RangeSelectionHelper::verifyArguments( const Sequence< beans::PropertyValue > & rArguments )
{
    Reference< chart2::data::XDataProvider > xDataProvider( m_xChartDocument->getDataProvider());
    if( ! xDataProvider.is())
        return false;

    return xDataProvider->createDataSourcePossible( rArguments );
}

OUString RangeSelectionHelper::getCellRangeContent( const OUString & rRangeStr )
{
    OUString aResult;

    Reference< sheet::XCellRangesAccess > xRangesAccess( getCellRangesAccess());
    if( xRangesAccess.is())
    {
        // @todo: the interface should provide a method to determine if a cell
        // range is correct, rather than waiting for an exception
        try
        {
            aResult = lcl_getTextFromRanges( xRangesAccess->getCellRangesByName( rRangeStr ) );
        }
        catch( const uno::Exception & ex )
        {
            ASSERT_EXCEPTION( ex );
        }
    }

    return aResult;
}

} //  namespace chart
<|endoftext|>


<commit_before>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/dom_ui/options/password_manager_handler.h"

#include "app/l10n_util.h"
#include "base/callback.h"
#include "base/stl_util-inl.h"
#include "base/string_number_conversions.h"
#include "base/utf_string_conversions.h"
#include "base/values.h"
#include "chrome/browser/prefs/pref_service.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/url_constants.h"
#include "grit/chromium_strings.h"
#include "grit/generated_resources.h"
#include "net/base/net_util.h"

PasswordManagerHandler::PasswordManagerHandler()
    : ALLOW_THIS_IN_INITIALIZER_LIST(populater_(this)),
      ALLOW_THIS_IN_INITIALIZER_LIST(exception_populater_(this)) {
}

PasswordManagerHandler::~PasswordManagerHandler() {
}

void PasswordManagerHandler::GetLocalizedValues(
    DictionaryValue* localized_strings) {
  DCHECK(localized_strings);

  localized_strings->SetString("passwordsTitle",
      l10n_util::GetStringUTF16(IDS_PASSWORDS_EXCEPTIONS_WINDOW_TITLE));
  localized_strings->SetString("savedPasswordsTitle",
      l10n_util::GetStringUTF16(IDS_PASSWORDS_SHOW_PASSWORDS_TAB_TITLE));
  localized_strings->SetString("passwordExceptionsTitle",
      l10n_util::GetStringUTF16(IDS_PASSWORDS_EXCEPTIONS_TAB_TITLE));
  localized_strings->SetString("passwordsSiteColumn",
      l10n_util::GetStringUTF16(IDS_PASSWORDS_PAGE_VIEW_SITE_COLUMN));
  localized_strings->SetString("passwordsUsernameColumn",
      l10n_util::GetStringUTF16(IDS_PASSWORDS_PAGE_VIEW_USERNAME_COLUMN));
  localized_strings->SetString("passwordsRemoveButton",
      l10n_util::GetStringUTF16(IDS_PASSWORDS_PAGE_VIEW_REMOVE_BUTTON));
  localized_strings->SetString("passwordsRemoveAllButton",
      l10n_util::GetStringUTF16(IDS_PASSWORDS_PAGE_VIEW_REMOVE_ALL_BUTTON));
  localized_strings->SetString("passwordsShowButton",
      l10n_util::GetStringUTF16(IDS_PASSWORDS_PAGE_VIEW_SHOW_BUTTON));
  localized_strings->SetString("passwordsHideButton",
      l10n_util::GetStringUTF16(IDS_PASSWORDS_PAGE_VIEW_HIDE_BUTTON));
  localized_strings->SetString("passwordsRemoveAllTitle",
      l10n_util::GetStringUTF16(
          IDS_PASSWORDS_PAGE_VIEW_CAPTION_DELETE_ALL_PASSWORDS));
  localized_strings->SetString("passwordsRemoveAllWarning",
      l10n_util::GetStringUTF16(
          IDS_PASSWORDS_PAGE_VIEW_TEXT_DELETE_ALL_PASSWORDS));
}

void PasswordManagerHandler::Initialize() {
  // We should not cache dom_ui_->GetProfile(). See crosbug.com/6304.
}

void PasswordManagerHandler::RegisterMessages() {
  DCHECK(dom_ui_);

  dom_ui_->RegisterMessageCallback("updatePasswordLists",
      NewCallback(this, &PasswordManagerHandler::UpdatePasswordLists));
  dom_ui_->RegisterMessageCallback("removeSavedPassword",
      NewCallback(this, &PasswordManagerHandler::RemoveSavedPassword));
  dom_ui_->RegisterMessageCallback("removePasswordException",
      NewCallback(this, &PasswordManagerHandler::RemovePasswordException));
  dom_ui_->RegisterMessageCallback("removeAllSavedPasswords",
      NewCallback(this, &PasswordManagerHandler::RemoveAllSavedPasswords));
  dom_ui_->RegisterMessageCallback("removeAllPasswordExceptions", NewCallback(
      this, &PasswordManagerHandler::RemoveAllPasswordExceptions));
}

PasswordStore* PasswordManagerHandler::GetPasswordStore() {
  return dom_ui_->GetProfile()->GetPasswordStore(Profile::EXPLICIT_ACCESS);
}

void PasswordManagerHandler::UpdatePasswordLists(const ListValue* args) {
  languages_ =
      dom_ui_->GetProfile()->GetPrefs()->GetString(prefs::kAcceptLanguages);
  populater_.Populate();
  exception_populater_.Populate();
}

void PasswordManagerHandler::RemoveSavedPassword(const ListValue* args) {
  std::string string_value = WideToUTF8(ExtractStringValue(args));
  int index;
  base::StringToInt(string_value, &index);

  GetPasswordStore()->RemoveLogin(*password_list_[index]);
  delete password_list_[index];
  password_list_.erase(password_list_.begin() + index);
  SetPasswordList();
}

void PasswordManagerHandler::RemovePasswordException(
    const ListValue* args) {
  std::string string_value = WideToUTF8(ExtractStringValue(args));
  int index;
  base::StringToInt(string_value, &index);

  GetPasswordStore()->RemoveLogin(*password_exception_list_[index]);
  delete password_exception_list_[index];
  password_exception_list_.erase(password_exception_list_.begin() + index);
  SetPasswordExceptionList();
}

void PasswordManagerHandler::RemoveAllSavedPasswords(
    const ListValue* args) {
  PasswordStore* store = GetPasswordStore();
  for (size_t i = 0; i < password_list_.size(); ++i)
    store->RemoveLogin(*password_list_[i]);
  STLDeleteElements(&password_list_);
  SetPasswordList();
}

void PasswordManagerHandler::RemoveAllPasswordExceptions(
    const ListValue* args) {
  PasswordStore* store = GetPasswordStore();
  for (size_t i = 0; i < password_exception_list_.size(); ++i)
    store->RemoveLogin(*password_exception_list_[i]);
  STLDeleteElements(&password_exception_list_);
  SetPasswordExceptionList();
}

void PasswordManagerHandler::SetPasswordList() {
  ListValue entries;
  for (size_t i = 0; i < password_list_.size(); ++i) {
    ListValue* entry = new ListValue();
    entry->Append(new StringValue(net::FormatUrl(password_list_[i]->origin,
                                                 languages_)));
    entry->Append(new StringValue(password_list_[i]->username_value));
    entry->Append(new StringValue(password_list_[i]->password_value));
    entries.Append(entry);
  }

  dom_ui_->CallJavascriptFunction(
      L"PasswordManager.setSavedPasswordsList", entries);
}

void PasswordManagerHandler::SetPasswordExceptionList() {
  ListValue entries;
  for (size_t i = 0; i < password_exception_list_.size(); ++i) {
    entries.Append(new StringValue(
        net::FormatUrl(password_exception_list_[i]->origin, languages_)));
  }

  dom_ui_->CallJavascriptFunction(
      L"PasswordManager.setPasswordExceptionsList", entries);
}

void PasswordManagerHandler::PasswordListPopulater::Populate() {
  DCHECK(!pending_login_query_);
  PasswordStore* store = page_->GetPasswordStore();
  if (store != NULL)
    pending_login_query_ = store->GetAutofillableLogins(this);
  else
    LOG(ERROR) << "No password store! Cannot display passwords.";
}

void PasswordManagerHandler::PasswordListPopulater::
    OnPasswordStoreRequestDone(int handle,
    const std::vector<webkit_glue::PasswordForm*>& result) {
  DCHECK_EQ(pending_login_query_, handle);
  pending_login_query_ = 0;
  page_->password_list_ = result;
  page_->SetPasswordList();
}

void PasswordManagerHandler::PasswordExceptionListPopulater::Populate() {
  DCHECK(!pending_login_query_);
  PasswordStore* store = page_->GetPasswordStore();
  if (store != NULL)
    pending_login_query_ = store->GetBlacklistLogins(this);
  else
    LOG(ERROR) << "No password store! Cannot display exceptions.";
}

void PasswordManagerHandler::PasswordExceptionListPopulater::
    OnPasswordStoreRequestDone(int handle,
    const std::vector<webkit_glue::PasswordForm*>& result) {
  DCHECK_EQ(pending_login_query_, handle);
  pending_login_query_ = 0;
  page_->password_exception_list_ = result;
  page_->SetPasswordExceptionList();
}
<commit_msg>DOMUI: Don't call SetString for fields that doesn't exist in the Password Manager.<commit_after>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/dom_ui/options/password_manager_handler.h"

#include "app/l10n_util.h"
#include "base/callback.h"
#include "base/stl_util-inl.h"
#include "base/string_number_conversions.h"
#include "base/utf_string_conversions.h"
#include "base/values.h"
#include "chrome/browser/prefs/pref_service.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/url_constants.h"
#include "grit/chromium_strings.h"
#include "grit/generated_resources.h"
#include "net/base/net_util.h"

PasswordManagerHandler::PasswordManagerHandler()
    : ALLOW_THIS_IN_INITIALIZER_LIST(populater_(this)),
      ALLOW_THIS_IN_INITIALIZER_LIST(exception_populater_(this)) {
}

PasswordManagerHandler::~PasswordManagerHandler() {
}

void PasswordManagerHandler::GetLocalizedValues(
    DictionaryValue* localized_strings) {
  DCHECK(localized_strings);

  localized_strings->SetString("passwordsTitle",
      l10n_util::GetStringUTF16(IDS_PASSWORDS_EXCEPTIONS_WINDOW_TITLE));
  localized_strings->SetString("savedPasswordsTitle",
      l10n_util::GetStringUTF16(IDS_PASSWORDS_SHOW_PASSWORDS_TAB_TITLE));
  localized_strings->SetString("passwordExceptionsTitle",
      l10n_util::GetStringUTF16(IDS_PASSWORDS_EXCEPTIONS_TAB_TITLE));
  localized_strings->SetString("passwordsSiteColumn",
      l10n_util::GetStringUTF16(IDS_PASSWORDS_PAGE_VIEW_SITE_COLUMN));
  localized_strings->SetString("passwordsUsernameColumn",
      l10n_util::GetStringUTF16(IDS_PASSWORDS_PAGE_VIEW_USERNAME_COLUMN));
  localized_strings->SetString("passwordsRemoveButton",
      l10n_util::GetStringUTF16(IDS_PASSWORDS_PAGE_VIEW_REMOVE_BUTTON));
  localized_strings->SetString("passwordsRemoveAllButton",
      l10n_util::GetStringUTF16(IDS_PASSWORDS_PAGE_VIEW_REMOVE_ALL_BUTTON));
  localized_strings->SetString("passwordsRemoveAllTitle",
      l10n_util::GetStringUTF16(
          IDS_PASSWORDS_PAGE_VIEW_CAPTION_DELETE_ALL_PASSWORDS));
  localized_strings->SetString("passwordsRemoveAllWarning",
      l10n_util::GetStringUTF16(
          IDS_PASSWORDS_PAGE_VIEW_TEXT_DELETE_ALL_PASSWORDS));
}

void PasswordManagerHandler::Initialize() {
  // We should not cache dom_ui_->GetProfile(). See crosbug.com/6304.
}

void PasswordManagerHandler::RegisterMessages() {
  DCHECK(dom_ui_);

  dom_ui_->RegisterMessageCallback("updatePasswordLists",
      NewCallback(this, &PasswordManagerHandler::UpdatePasswordLists));
  dom_ui_->RegisterMessageCallback("removeSavedPassword",
      NewCallback(this, &PasswordManagerHandler::RemoveSavedPassword));
  dom_ui_->RegisterMessageCallback("removePasswordException",
      NewCallback(this, &PasswordManagerHandler::RemovePasswordException));
  dom_ui_->RegisterMessageCallback("removeAllSavedPasswords",
      NewCallback(this, &PasswordManagerHandler::RemoveAllSavedPasswords));
  dom_ui_->RegisterMessageCallback("removeAllPasswordExceptions", NewCallback(
      this, &PasswordManagerHandler::RemoveAllPasswordExceptions));
}

PasswordStore* PasswordManagerHandler::GetPasswordStore() {
  return dom_ui_->GetProfile()->GetPasswordStore(Profile::EXPLICIT_ACCESS);
}

void PasswordManagerHandler::UpdatePasswordLists(const ListValue* args) {
  languages_ =
      dom_ui_->GetProfile()->GetPrefs()->GetString(prefs::kAcceptLanguages);
  populater_.Populate();
  exception_populater_.Populate();
}

void PasswordManagerHandler::RemoveSavedPassword(const ListValue* args) {
  std::string string_value = WideToUTF8(ExtractStringValue(args));
  int index;
  base::StringToInt(string_value, &index);

  GetPasswordStore()->RemoveLogin(*password_list_[index]);
  delete password_list_[index];
  password_list_.erase(password_list_.begin() + index);
  SetPasswordList();
}

void PasswordManagerHandler::RemovePasswordException(
    const ListValue* args) {
  std::string string_value = WideToUTF8(ExtractStringValue(args));
  int index;
  base::StringToInt(string_value, &index);

  GetPasswordStore()->RemoveLogin(*password_exception_list_[index]);
  delete password_exception_list_[index];
  password_exception_list_.erase(password_exception_list_.begin() + index);
  SetPasswordExceptionList();
}

void PasswordManagerHandler::RemoveAllSavedPasswords(
    const ListValue* args) {
  PasswordStore* store = GetPasswordStore();
  for (size_t i = 0; i < password_list_.size(); ++i)
    store->RemoveLogin(*password_list_[i]);
  STLDeleteElements(&password_list_);
  SetPasswordList();
}

void PasswordManagerHandler::RemoveAllPasswordExceptions(
    const ListValue* args) {
  PasswordStore* store = GetPasswordStore();
  for (size_t i = 0; i < password_exception_list_.size(); ++i)
    store->RemoveLogin(*password_exception_list_[i]);
  STLDeleteElements(&password_exception_list_);
  SetPasswordExceptionList();
}

void PasswordManagerHandler::SetPasswordList() {
  ListValue entries;
  for (size_t i = 0; i < password_list_.size(); ++i) {
    ListValue* entry = new ListValue();
    entry->Append(new StringValue(net::FormatUrl(password_list_[i]->origin,
                                                 languages_)));
    entry->Append(new StringValue(password_list_[i]->username_value));
    entry->Append(new StringValue(password_list_[i]->password_value));
    entries.Append(entry);
  }

  dom_ui_->CallJavascriptFunction(
      L"PasswordManager.setSavedPasswordsList", entries);
}

void PasswordManagerHandler::SetPasswordExceptionList() {
  ListValue entries;
  for (size_t i = 0; i < password_exception_list_.size(); ++i) {
    entries.Append(new StringValue(
        net::FormatUrl(password_exception_list_[i]->origin, languages_)));
  }

  dom_ui_->CallJavascriptFunction(
      L"PasswordManager.setPasswordExceptionsList", entries);
}

void PasswordManagerHandler::PasswordListPopulater::Populate() {
  DCHECK(!pending_login_query_);
  PasswordStore* store = page_->GetPasswordStore();
  if (store != NULL)
    pending_login_query_ = store->GetAutofillableLogins(this);
  else
    LOG(ERROR) << "No password store! Cannot display passwords.";
}

void PasswordManagerHandler::PasswordListPopulater::
    OnPasswordStoreRequestDone(int handle,
    const std::vector<webkit_glue::PasswordForm*>& result) {
  DCHECK_EQ(pending_login_query_, handle);
  pending_login_query_ = 0;
  page_->password_list_ = result;
  page_->SetPasswordList();
}

void PasswordManagerHandler::PasswordExceptionListPopulater::Populate() {
  DCHECK(!pending_login_query_);
  PasswordStore* store = page_->GetPasswordStore();
  if (store != NULL)
    pending_login_query_ = store->GetBlacklistLogins(this);
  else
    LOG(ERROR) << "No password store! Cannot display exceptions.";
}

void PasswordManagerHandler::PasswordExceptionListPopulater::
    OnPasswordStoreRequestDone(int handle,
    const std::vector<webkit_glue::PasswordForm*>& result) {
  DCHECK_EQ(pending_login_query_, handle);
  pending_login_query_ = 0;
  page_->password_exception_list_ = result;
  page_->SetPasswordExceptionList();
}
<|endoftext|>