Commit 175a2887 authored by Victor Lamoine's avatar Victor Lamoine
Browse files

Initial commit

parents
Pipeline #173632814 failed with stage
in 1 minute and 45 seconds
image: ros:melodic-robot
before_script:
- apt update >/dev/null && apt install -y git >/dev/null
- git clone https://gitlab.com/VictorLamoine/ros_gitlab_ci.git
- source ros_gitlab_ci/gitlab-ci.bash >/dev/null
cache:
paths:
- ccache/
catkin lint:
stage: build
image: ros:melodic-ros-core
before_script:
- apt update >/dev/null
- apt install -y python-catkin-lint python-rosdep >/dev/null
- rosdep init >/dev/null && rosdep update >/dev/null
script:
- catkin_lint -W2 .
catkin_make:
stage: build
script:
- catkin_make
cmake_minimum_required(VERSION 3.2)
project(serial_temperatures)
add_compile_options(-Wall -Wextra)
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
## Find catkin macros and libraries
find_package(catkin REQUIRED COMPONENTS
roscpp
std_msgs
)
## Find Qt5
set(CMAKE_AUTOMOC ON)
find_package(Qt5Widgets REQUIRED)
find_package(Qt5SerialPort REQUIRED)
################################################
## Declare ROS messages, services and actions ##
################################################
################################################
## Declare ROS dynamic reconfigure parameters ##
################################################
###################################
## catkin specific configuration ##
###################################
catkin_package(
INCLUDE_DIRS
include
LIBRARIES
${PROJECT_NAME}_serialportreader
CATKIN_DEPENDS
roscpp
std_msgs
DEPENDS
Qt5SerialPort
Qt5Widgets
)
###########
## Build ##
###########
include_directories(
include
${catkin_INCLUDE_DIRS}
)
add_library(
${PROJECT_NAME}_serialportreader
include/${PROJECT_NAME}/serialportreader.hpp
src/serialportreader.cpp
)
target_link_libraries(
${PROJECT_NAME}_serialportreader
Qt5::Widgets
Qt5::SerialPort
)
add_executable(
${PROJECT_NAME}
src/publishers.cpp
)
target_link_libraries(
${PROJECT_NAME}
${PROJECT_NAME}_serialportreader
Qt5::Widgets
Qt5::SerialPort
${catkin_LIBRARIES}
)
add_dependencies(
${PROJECT_NAME}
${PROJECT_NAME}_serialportreader
)
set_target_properties(
${PROJECT_NAME}
PROPERTIES
OUTPUT_NAME
"publishers"
)
#############
## Install ##
#############
## Mark executables and/or libraries for installation
install(
TARGETS
${PROJECT_NAME}
${PROJECT_NAME}_serialportreader
ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
)
## Mark cpp header files for installation
install(
DIRECTORY
include/${PROJECT_NAME}/
DESTINATION
${CATKIN_PACKAGE_INCLUDE_DESTINATION}
)
#############
## Testing ##
#############
BSD-3-Clause-Attribution License
2020, Institut Maupertuis
http://www.institutmaupertuis.fr
4 contour Antoine de Saint Exupéry
Bruz, 35170, France
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
2. Redistributions 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.
3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
4. Redistributions of any form whatsoever must retain the following acknowledgment: 'This product includes software developed by the "Institut Maupertuis, France" (http://www.institutmaupertuis.fr).'
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 HOLDER 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.
[![Institut Maupertuis logo](http://www.institutmaupertuis.fr/media/gabarit/logo.png)](http://www.institutmaupertuis.fr)
#ifndef SERIAL_TEMPERATURES_SERIALPORTREADER_HPP
#define SERIAL_TEMPERATURES_SERIALPORTREADER_HPP
#include <memory>
#include <QByteArray>
#include <QCoreApplication>
#include <QDateTime>
#include <QObject>
#include <QtSerialPort/QSerialPort>
#include <ros/publisher.h>
#include <ros/ros.h>
#include <std_msgs/Float32.h>
class SerialPortReader : public QObject
{
Q_OBJECT
public:
SerialPortReader(QSerialPort *serial_port, QObject *parent = 0);
~SerialPortReader();
std::shared_ptr<std::vector<ros::Publisher>> publishers_;
std::shared_ptr<ros::NodeHandle> nh_;
Q_SIGNALS:
void newLineFetched(QString line, QDateTime date_time);
private Q_SLOTS:
void readData();
void handleError(QSerialPort::SerialPortError error);
void publishTemperatures(QString line, QDateTime date_time);
private:
QSerialPort *serial_port_;
QByteArray data_read_;
};
#endif
<?xml version="1.0"?>
<package format="2">
<name>serial_temperatures</name>
<version>0.0.1</version>
<description>Publish temperatures received over serial</description>
<author>Victor Lamoine - Institut Maupertuis</author>
<maintainer email="victor.lamoine@gmail.com">Victor Lamoine</maintainer>
<license>BSD-3-Clause-Attribution</license>
<buildtool_depend>catkin</buildtool_depend>
<depend>roscpp</depend>
<depend>std_msgs</depend>
</package>
#include <QtCore>
#include <ros/ros.h>
#include <serial_temperatures/serialportreader.hpp>
using std::cout;
using std::cerr;
using std::endl;
int main(int argc, char *argv[])
{
ros::init(argc, argv, "serial_temperatures");
std::shared_ptr<ros::NodeHandle> nh(std::make_shared<ros::NodeHandle>());
ros::AsyncSpinner s(2);
s.start();
std::shared_ptr<std::vector<ros::Publisher>> publishers;
publishers = std::make_shared<std::vector<ros::Publisher>>();
publishers->resize(6);
publishers->at(0) = nh->advertise<std_msgs::Float32>("/ram/sensors/thermocouples/0", 5);
publishers->at(1) = nh->advertise<std_msgs::Float32>("/ram/sensors/thermocouples/1", 5);
publishers->at(2) = nh->advertise<std_msgs::Float32>("/ram/sensors/thermocouples/2", 5);
publishers->at(3) = nh->advertise<std_msgs::Float32>("/ram/sensors/thermocouples/3", 5);
publishers->at(4) = nh->advertise<std_msgs::Float32>("/ram/sensors/thermocouples/4", 5);
publishers->at(5) = nh->advertise<std_msgs::Float32>("/ram/sensors/thermocouples/5", 5);
QCoreApplication app(argc, argv);
QSerialPort *serial_port(new QSerialPort);
SerialPortReader *serial_port_reader(new SerialPortReader(serial_port));
serial_port_reader->publishers_ = publishers;
serial_port_reader->nh_ = nh;
std::string port("/dev/ttyACM0");
nh->getParam("port", port);
int baudrate(115200);
nh->getParam("baudrate", baudrate);
serial_port->setPortName(port.c_str());
serial_port->setBaudRate(baudrate);
if (!serial_port->open(QIODevice::ReadOnly))
{
ROS_ERROR_STREAM("Could not open port " << serial_port->portName().toStdString());
return 1;
}
ROS_INFO_STREAM("Start publishing");
return app.exec();
}
#include <serial_temperatures/serialportreader.hpp>
SerialPortReader::SerialPortReader(QSerialPort *serial_port,
QObject *parent) :
QObject(parent),
serial_port_(serial_port)
{
connect(serial_port, &QSerialPort::readyRead, this, &SerialPortReader::readData);
connect(serial_port, qOverload<QSerialPort::SerialPortError>(&QSerialPort::error), this, &SerialPortReader::handleError);
connect(this, &SerialPortReader::newLineFetched, this, &SerialPortReader::publishTemperatures);
}
SerialPortReader::~SerialPortReader()
{
}
void SerialPortReader::readData()
{
data_read_.append(serial_port_->readAll());
if (!data_read_.contains('\n'))
return; // Wait for a complete line
// Keep only last message if there are multiple ones
const int last_lr(data_read_.lastIndexOf('\n'));
// Remove extra characters after last \n
if (last_lr != data_read_.size() - 1)
data_read_.truncate(last_lr + 1);
// While first \n is not last
int index(data_read_.indexOf('\n'));
while (index != data_read_.size() - 1)
{
// Remove characters on the left
data_read_ = data_read_.right(data_read_.size() - index - 1);
// Search for first \n, don't stop until it's the last character
index = data_read_.indexOf('\n');
}
QDateTime now(QDateTime::currentDateTime()); // Not good because it's the stamp of the last byte message!
Q_EMIT newLineFetched(data_read_, now);
data_read_.clear();
}
void SerialPortReader::handleError(QSerialPort::SerialPortError errror)
{
if (errror == QSerialPort::ReadError)
{
ROS_ERROR_STREAM("An I/O error occurred while reading the data from port " << serial_port_->portName().toStdString()
<< ", error:" << serial_port_->errorString().toStdString());
}
}
void SerialPortReader::publishTemperatures(QString line, QDateTime)
{
if (!publishers_)
return;
QRegExp rx("[;]");
QStringList list = line.split(rx, QString::SkipEmptyParts);
if (list.size() != 6)
{
ROS_WARN_STREAM("Wrong message received. Expected 6, got " << list.size());
return;
}
std_msgs::Float32 msg;
for (int i(0); i < 6; ++i)
{
bool ok;
double value(list.at(i).toDouble(&ok)); // Check that conversion is successful
if (!ok)
{
ROS_ERROR_STREAM("Could not convert " << list.at(i).toStdString());
break;
}
msg.data = value;
publishers_->at(i).publish(msg);
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment