<|start_filename|>lms151/test/test_buffer.cpp<|end_filename|>
/*
 * lms_buffer.h
 *
 *  Author: <NAME> <<EMAIL>>
 ***************************************************************************
 *   This library is free software; you can redistribute it and/or         *
 *   modify it under the terms of the GNU Lesser General Public            *
 *   License as published by the Free Software Foundation; either          *
 *   version 2.1 of the License, or (at your option) any later version.    *
 *                                                                         *
 *   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                                *
 *                                                                         *
 ***************************************************************************/

#include "LMS1xx/lms_buffer.h"
#include "gtest/gtest.h"

#include <errno.h>
#include <unistd.h>


class BufferTest : public :: testing :: Test
{
  virtual void SetUp()
  {
    ASSERT_NE(-1, pipe(fds_));
    ASSERT_NE(0, fds_[0]);
    ASSERT_NE(0, fds_[1]);
  }

  virtual void TearDown()
  {
    close(fds_[0]);
    close(fds_[1]);
  }

protected:
  LMSBuffer buf_;
  int fds_[2];
};


TEST_F(BufferTest, single)
{
  ASSERT_NE(-1, write(fds_[1], "\x02ghij\x03", 6)) << "Error code: " << errno;
  buf_.readFrom(fds_[0]);

  // Final char should have been transformed to null terminator.
  ASSERT_STREQ("\x02ghij", buf_.getNextBuffer());
}

TEST_F(BufferTest, split)
{
  ASSERT_NE(-1, write(fds_[1], "\x02ghij", 5)) << "Error code: " << errno;
  buf_.readFrom(fds_[0]);
  EXPECT_EQ(NULL, buf_.getNextBuffer());

  ASSERT_NE(-1, write(fds_[1], "abcde", 5)) << "Error code: " << errno;
  buf_.readFrom(fds_[0]);
  EXPECT_EQ(NULL, buf_.getNextBuffer());

  ASSERT_NE(-1, write(fds_[1], "fghijk\x03", 7)) << "Error code: " << errno;
  buf_.readFrom(fds_[0]);
  EXPECT_STREQ("\x02ghijabcdefghijk", buf_.getNextBuffer());
}

TEST_F(BufferTest, extra_bytes)
{
  ASSERT_NE(-1, write(fds_[1], "abc\x02ghijk\x03stuv", 14)) << "Error code: " << errno;
  buf_.readFrom(fds_[0]);
  EXPECT_STREQ("\x02ghijk", buf_.getNextBuffer());
  buf_.popLastBuffer();

  ASSERT_NE(-1, write(fds_[1], "abc\x02ghjk\x03stuv", 14)) << "Error code: " << errno;
  buf_.readFrom(fds_[0]);
  EXPECT_STREQ("\x02ghjk", buf_.getNextBuffer());
}

TEST_F(BufferTest, multiple)
{
  ASSERT_NE(-1, write(fds_[1], "\x02gh\x03\x02jk\x03xyz\x02ty\x03", 15)) << "Error code: " << errno;
  buf_.readFrom(fds_[0]);

  EXPECT_STREQ("\x02gh", buf_.getNextBuffer());
  buf_.popLastBuffer();
  EXPECT_STREQ("\x02jk", buf_.getNextBuffer());
  buf_.popLastBuffer();
  EXPECT_STREQ("\x02ty", buf_.getNextBuffer());
  buf_.popLastBuffer();
}

int main(int argc, char **argv)
{
  testing::InitGoogleTest(&argc, argv);
  return RUN_ALL_TESTS();
}


<|start_filename|>lms151/include/LMS1xx/LMS1xx.h<|end_filename|>
/*
 * LMS1xx.h
 *
 *  Created on: 09-08-2010
 *  Author: <NAME>
 ***************************************************************************
 *   This library is free software; you can redistribute it and/or         *
 *   modify it under the terms of the GNU Lesser General Public            *
 *   License as published by the Free Software Foundation; either          *
 *   version 2.1 of the License, or (at your option) any later version.    *
 *                                                                         *
 *   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                                *
 *                                                                         *
 ***************************************************************************/

#ifndef LMS1XX_H_
#define LMS1XX_H_

#include <LMS1xx/lms_buffer.h>
#include <LMS1xx/lms_structs.h>
#include <string>
#include <stdint.h>

typedef enum
{
  undefined = 0,
  initialisation = 1,
  configuration = 2,
  idle = 3,
  rotated = 4,
  in_preparation = 5,
  ready = 6,
  ready_for_measurement = 7
} status_t;

/*!
* @class LMS1xx
* @brief Class responsible for communicating with LMS1xx device.
*
* @author <NAME>
*/

class LMS1xx
{
public:
  LMS1xx();
  virtual ~LMS1xx();

  /*!
  * @brief Connect to LMS1xx.
  * @param host LMS1xx host name or ip address.
  * @param port LMS1xx port number.
  */
  void connect(std::string host, int port = 2111);

  /*!
  * @brief Disconnect from LMS1xx device.
  */
  void disconnect();

  /*!
  * @brief Get status of connection.
  * @returns connected or not.
  */
  bool isConnected();

  /*!
  * @brief Start measurements.
  * After receiving this command LMS1xx unit starts spinning laser and measuring.
  */
  void startMeas();

  /*!
  * @brief Stop measurements.
  * After receiving this command LMS1xx unit stop spinning laser and measuring.
  */
  void stopMeas();

  /*!
  * @brief Get current status of LMS1xx device.
  * @returns status of LMS1xx device.
  */
  status_t queryStatus();

  /*!
  * @brief Log into LMS1xx unit.
  * Increase privilege level, giving ability to change device configuration.
  */
  void login();

  /*!
  * @brief Get current scan configuration.
  * Get scan configuration :
  * - scanning frequency.
  * - scanning resolution.
  * - start angle.
  * - stop angle.
  * @returns scanCfg structure.
  */
  scanCfg getScanCfg() const;

  /*!
  * @brief Set scan configuration.
  * Get scan configuration :
  * - scanning frequency.
  * - scanning resolution.
  * - start angle.
  * - stop angle.
  * @param cfg structure containing scan configuration.
  */
  void setScanCfg(const scanCfg &cfg);

  /*!
  * @brief Set scan data configuration.
  * Set format of scan message returned by device.
  * @param cfg structure containing scan data configuration.
  */
  void setScanDataCfg(const scanDataCfg &cfg);

  /*!
  * @brief Get current output range configuration.
  * Get output range configuration :
  * - scanning resolution.
  * - start angle.
  * - stop angle.
  * @returns scanOutputRange structure.
  */
  scanOutputRange getScanOutputRange() const;

  /*!
  * @brief Start or stop continuous data acquisition.
  * After reception of this command device start or stop continuous data stream containing scan messages.
  * @param start 1 : start 0 : stop
  */
  void scanContinous(int start);

  /*!
  * @brief Receive single scan message.
  * @return true if scan was read successfully, false if error or timeout. False implies that higher level
  *         logic should take correct action such as reopening the connection.
  */
  bool getScanData(scanData* scan_data);

  /*!
  * @brief Save data permanently.
  * Parameters are saved in the EEPROM of the LMS and will also be available after the device is switched off and on again.
  *
  */
  void saveConfig();

  /*!
  * @brief The device is returned to the measurement mode after configuration.
  *
  */
  void startDevice();

protected:
  /*!
  * @brief Receive single scan message.
  * @param data pointer to scanData buffer structure.
  */
  static void parseScanData(char* buf, scanData* data);

  bool connected_;
  LMSBuffer buffer_;
  int socket_fd_;
};

#endif /* LMS1XX_H_ */



<|start_filename|>lms151/include/LMS1xx/lms_structs.h<|end_filename|>
/*
 * lms_structs.h
 *
 *  Author: <NAME>
 *          <NAME> <<EMAIL>>
 ***************************************************************************
 *   This library is free software; you can redistribute it and/or         *
 *   modify it under the terms of the GNU Lesser General Public            *
 *   License as published by the Free Software Foundation; either          *
 *   version 2.1 of the License, or (at your option) any later version.    *
 *                                                                         *
 *   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                                *
 *                                                                         *
 ***************************************************************************/

#ifndef LMS1XX_LMS_STRUCTS_H_
#define LMS1XX_LMS_STRUCTS_H_

#include <stdint.h>

/*!
* @class scanCfg
* @brief Structure containing scan configuration.
*
* @author <NAME>
*/
struct scanCfg
{
  /*!
   * @brief Scanning frequency.
   * 1/100 Hz
   */
  int scaningFrequency;

  /*!
   * @brief Scanning resolution.
   * 1/10000 degree
   */
  int angleResolution;

  /*!
   * @brief Start angle.
   * 1/10000 degree
   */
  int startAngle;

  /*!
   * @brief Stop angle.
   * 1/10000 degree
   */
  int stopAngle;
};

/*!
* @class scanDataCfg
* @brief Structure containing scan data configuration.
*
* @author <NAME>
*/
struct scanDataCfg
{

  /*!
   * @brief Output channels.
   * Defines which output channel is activated.
   */
  int outputChannel;

  /*!
   * @brief Remission.
   * Defines whether remission values are output.
   */
  bool remission;

  /*!
   * @brief Remission resolution.
   * Defines whether the remission values are output with 8-bit or 16bit resolution.
   */
  int resolution;

  /*!
   * @brief Encoders channels.
   * Defines which output channel is activated.
   */
  int encoder;

  /*!
   * @brief Position.
   * Defines whether position values are output.
   */
  bool position;

  /*!
   * @brief Device name.
   * Determines whether the device name is to be output.
   */
  bool deviceName;

  bool timestamp;

  /*!
   * @brief Output interval.
   * Defines which scan is output.
   *
   * 01 every scan\n
   * 02 every 2nd scan\n
   * ...\n
   * 50000 every 50000th scan
   */
  int outputInterval;
};

/*!
* @class outputRange
* @brief Structure containing scan output range configuration
*
* @author wpd
*/
struct scanOutputRange
{
  /*!
   * @brief Scanning resolution.
   * 1/10000 degree
   */
  int angleResolution;

  /*!
   * @brief Start angle.
   * 1/10000 degree
   */
  int startAngle;

  /*!
   * @brief Stop angle.
   * 1/10000 degree
   */
  int stopAngle;
};

/*!
* @class scanData
* @brief Structure containing single scan message.
*
* @author <NAME>
*/
struct scanData
{

  /*!
   * @brief Number of samples in dist1.
   *
   */
  int dist_len1;

  /*!
   * @brief Radial distance for the first reflected pulse
   *
   */
  uint16_t dist1[1082];

  /*!
   * @brief Number of samples in dist2.
   *
   */
  int dist_len2;

  /*!
   * @brief Radial distance for the second reflected pulse
   *
   */
  uint16_t dist2[1082];

  /*!
   * @brief Number of samples in rssi1.
   *
   */
  int rssi_len1;

  /*!
   * @brief Remission values for the first reflected pulse
   *
   */
  uint16_t rssi1[1082];

  /*!
   * @brief Number of samples in rssi2.
   *
   */
  int rssi_len2;

  /*!
   * @brief Remission values for the second reflected pulse
   *
   */
  uint16_t rssi2[1082];
};

#endif  // LMS1XX_LMS_STRUCTS_H_
