GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: src/catkin/hardware/blmc_drivers/src/serial_reader.cpp Lines: 1 76 1.3 %
Date: 2020-04-15 11:50:02 Branches: 2 62 3.2 %

Line Branch Exec Source
1
/**
2
 * @file serial_reader.cpp
3
 * @author Julian Viereck
4
 * \brief Wrapper for reading new-line terminated list of values from serial port.
5
 * @date 2020-01-24
6
 *
7
 * @copyright Copyright (c) 2018
8
 *
9
 */
10
11
#include "blmc_drivers/serial_reader.hpp"
12
#include <stdexcept>
13
#include <errno.h>
14
#include <fcntl.h>
15
#include <string.h>
16
#include <termios.h>
17
#include <unistd.h>
18
19
#include <iostream>
20
#include <unistd.h>
21
#include <fstream>
22
23
namespace rt = real_time_tools;
24
25
namespace blmc_drivers
26
{
27
28
SerialReader::SerialReader(const std::string &serial_port, const int &num_values)
29
{
30
    std::string serial_port_try;
31
    for (int i=0; i < 4; i++) {
32
        // HACK: Ignore the provided serial port and
33
        if (i == 0) {
34
            serial_port_try = "/dev/ttyACM";
35
        } else if (i == 1) {
36
            serial_port_try = "/dev/ttyACM0";
37
        } else if (i == 2) {
38
            serial_port_try = "/dev/ttyACM1";
39
        } else {
40
            std::cerr << "Unable to open serial port";
41
            has_error_ = true;
42
            return;
43
        }
44
        std::cout << "Try to open serial port at " << serial_port_try << std::endl;
45
        fd_ = open(serial_port_try.c_str(), O_RDWR | O_NOCTTY | O_NDELAY);
46
        if (fd_ != -1) {
47
            std::cout << "Opened serial port at " << serial_port_try << std::endl;
48
            break;
49
        }
50
    }
51
52
    struct termios options;
53
54
    fcntl(fd_, F_SETFL, FNDELAY);                    // Open the device in nonblocking mode
55
56
    // Set parameters
57
    tcgetattr(fd_, &options);                        // Get the current options of the port
58
    bzero(&options, sizeof(options));               // Clear all the options
59
    speed_t         Speed = B115200;
60
    cfsetispeed(&options, Speed);                   // Set the baud rate at 115200 bauds
61
    cfsetospeed(&options, Speed);
62
    options.c_cflag |= ( CLOCAL | CREAD |  CS8);    // Configure the device : 8 bits, no parity, no control
63
    options.c_iflag |= ( IGNPAR | IGNBRK );
64
    options.c_cc[VTIME]=0;                          // Timer unused
65
    options.c_cc[VMIN]=0;                           // At least on character before satisfy reading
66
    tcsetattr(fd_, TCSANOW, &options);               // Activate the settings
67
68
    latest_values_.resize(num_values);
69
70
    has_error_ = false;
71
    is_active_ = false;
72
    is_loop_active_ = true;
73
    // Launch the main processing loop.
74
    rt_thread_.create_realtime_thread(&SerialReader::loop, this);
75
}
76
77
void SerialReader::loop()
78
{
79
    int i = 0;
80
    int j = 0;
81
82
    int byte_read;
83
    int buffer_size = 128;
84
    char buffer[buffer_size];
85
    char line[buffer_size];
86
    int line_index = 0;
87
88
    static int c = 0;
89
    is_active_ = true;
90
    while (is_loop_active_) {
91
        int byte_consumed = 0;
92
        byte_read = read(fd_, buffer, buffer_size);
93
        while (byte_consumed < byte_read) {
94
            line[line_index++] = buffer[byte_consumed++];
95
            if (buffer[byte_consumed - 1] == '\n') {
96
                // Ignore the "\r\n" in the string.
97
                line[line_index - 1] = '\0';
98
                line[line_index - 2] = '\0';
99
                line_index -= 2;
100
101
                // Read the actual numbers from the line.
102
                int bytes_scanned_total = 0;
103
                int bytes_scanned;
104
                int number;
105
                mutex_.lock();
106
                for (int i = 0; i < latest_values_.size(); i++) {
107
                    sscanf(line + bytes_scanned_total, "%d %n", &number, &bytes_scanned);
108
                    if (bytes_scanned_total >= line_index) {
109
                        break;
110
                    }
111
                    bytes_scanned_total += bytes_scanned;
112
                    latest_values_[i] = number;
113
                }
114
                new_data_counter_ += 1;
115
                mutex_.unlock();
116
117
                line_index = 0;
118
            }
119
        }
120
        usleep(100);
121
    }
122
}
123
124
SerialReader::~SerialReader()
125
{
126
    is_loop_active_ = false;
127
    rt_thread_.join();
128
    close(fd_);
129
}
130
131
int SerialReader::fill_vector(std::vector<int>& values)
132
{
133
    mutex_.lock();
134
    if (new_data_counter_ == 0) {
135
        missed_data_counter_ += 1;
136
    } else {
137
        missed_data_counter_ = 0;
138
    }
139
    new_data_counter_ = 0;
140
    values = latest_values_;
141
    mutex_.unlock();
142
143
    return missed_data_counter_;
144
}
145
146

3
} // namespace blmc_drivers