I have been working on a program that is supposed to balance a robot. I want to have the motors driven in separate threads, but I keep getting these errors:
In file included from /usr/arm-linux-gnueabi/include/c++/6/thread:39:0,
from /src/include/includes.hpp:5,
from /src/src/main.cpp:1:
/usr/arm-linux-gnueabi/include/c++/6/functional: In instantiation of 'struct std::_Bind_simple<void (*(const char*, std::reference_wrapper<int>, std::reference_wrapper<bool>))(std::__cxx11::basic_string<char>, int*, bool*)>':
/usr/arm-linux-gnueabi/include/c++/6/thread:138:26: required from 'std::thread::thread(_Callable&&, _Args&& ...) [with _Callable = void (&)(std::__cxx11::basic_string<char>, int*, bool*); _Args = {const char (&)[15], std::reference_wrapper<int>, std::reference_wrapper<bool>}]'
/src/src/main.cpp:10:83: required from here
/usr/arm-linux-gnueabi/include/c++/6/functional:1365:61: error: no type named 'type' in 'class std::result_of<void (*(const char*, std::reference_wrapper<int>, std::reference_wrapper<bool>))(std::__cxx11::basic_string<char>, int*, bool*)>'
typedef typename result_of<_Callable(_Args...)>::type result_type;
^~~~~~~~~~~
/usr/arm-linux-gnueabi/include/c++/6/functional:1386:9: error: no type named 'type' in 'class std::result_of<void (*(const char*, std::reference_wrapper<int>, std::reference_wrapper<bool>))(std::__cxx11::basic_string<char>, int*, bool*)>'
_M_invoke(_Index_tuple<_Indices...>)
^~~~~~~~~
CMakeFiles/balance.dir/build.make:62: recipe for target 'CMakeFiles/balance.dir/src/main.cpp.o' failed
make[2]: *** [CMakeFiles/balance.dir/src/main.cpp.o] Error 1
CMakeFiles/Makefile2:67: recipe for target 'CMakeFiles/balance.dir/all' failed
make[1]: *** [CMakeFiles/balance.dir/all] Error 2
Makefile:83: recipe for target 'all' failed
make: *** [all] Error 2
My code looks like this:
main.cpp
#include "includes.hpp"
int main() {
PID pid(1, 0, 0);
int rightSpeed = 0;
int leftSpeed = 0;
bool end = false;
std::thread m_right(motorThread, OUTPUT_A, std::ref(rightSpeed), std::ref(end));
std::thread m_left(motorThread, OUTPUT_D, std::ref(leftSpeed), std::ref(end));
gyro_sensor gyro(INPUT_2);
gyro.set_mode(gyro_sensor::mode_gyro_ang);
while(button::enter.pressed() == false) {
rightSpeed, leftSpeed = pid.call(gyro.angle(false));
}
end = true;
m_right.join();
m_left.join();
return 0;
}
motorThread.cpp
#include "includes.hpp"
void motorThread(address_type address, int * speedVar, bool * endVar) {
motor m_motor(address);
m_motor.run_direct();
while(*endVar == false) {
m_motor.set_duty_cycle_sp(*speedVar);
}
}
includes.hpp
#pragma once
#include <iostream>
#include <string>
#include <thread>
#include <functional>
#include "ev3dev.h"
#include "pid.hpp"
using namespace ev3dev;
void motorThread(address_type address, int * speedVar, bool * endVar);
I am using the ev3dev docker image (page that tells you how to use it) with arm-linux-gnueabi-g++ 6.3.0 on Arch Linux.