54#if __linux__ || __APPLE__
63uint64_t get_time_usec()
65 static struct timeval _time_stamp;
66 gettimeofday(&_time_stamp,
nullptr);
67 return static_cast<uint64_t
>(_time_stamp.tv_sec) * 1000000UL +
static_cast<uint64_t
>(_time_stamp.tv_usec);
82void set_position(
float x,
float y,
float z, mavlink_set_position_target_local_ned_t& sp)
85 MAVLINK_MSG_SET_POSITION_TARGET_LOCAL_NED_POSITION;
87 sp.coordinate_frame = MAV_FRAME_LOCAL_NED;
93 LOG_INFO(
"autopilot_interface.cpp - POSITION SETPOINT XYZ = [ {} , {} , {} ] \n", sp.x, sp.y, sp.z);
102void set_velocity(
float vx,
float vy,
float vz, mavlink_set_position_target_local_ned_t& sp)
105 MAVLINK_MSG_SET_POSITION_TARGET_LOCAL_NED_VELOCITY;
107 sp.coordinate_frame = MAV_FRAME_LOCAL_NED;
113 LOG_INFO(
"autopilot_interface.cpp - VELOCITY SETPOINT UVW = [ {} , {} , {} ] \n", sp.vx, sp.vy, sp.vz);
122void set_acceleration(
float ,
float ,
float , mavlink_set_position_target_local_ned_t& )
125 LOG_ERROR(
"autopilot_interface.cpp - set_acceleration doesn't work yet \n");
145void set_yaw(
float yaw, mavlink_set_position_target_local_ned_t& sp)
148 MAVLINK_MSG_SET_POSITION_TARGET_LOCAL_NED_YAW_ANGLE;
152 LOG_INFO(
"autopilot_interface.cpp - POSITION SETPOINT YAW = {} \n", sp.yaw);
161void set_yaw_rate(
float yaw_rate, mavlink_set_position_target_local_ned_t& sp)
164 MAVLINK_MSG_SET_POSITION_TARGET_LOCAL_NED_YAW_RATE;
166 sp.yaw_rate = yaw_rate;
176Autopilot_Interface::Autopilot_Interface(
const std::shared_ptr<Generic_Port>& port_) : port(port_)
178 current_messages.sysid = system_id;
179 current_messages.compid = autopilot_id;
185void Autopilot_Interface::setPort(
const std::shared_ptr<Generic_Port>& port_new)
193void Autopilot_Interface::update_setpoint(mavlink_set_position_target_local_ned_t setpoint)
195 std::lock_guard<std::mutex> lock(current_setpoint.mutex);
196 current_setpoint.data = setpoint;
202void Autopilot_Interface::read_messages()
204 bool success =
false;
205 bool received_all =
false;
206 Time_Stamps this_timestamps;
209 while (!received_all and !time_to_exit)
214 mavlink_message_t message;
215 success = port->read_message(message);
224 current_messages.sysid = message.sysid;
225 current_messages.compid = message.compid;
228 switch (message.msgid)
230 case MAVLINK_MSG_ID_HEARTBEAT:
233 mavlink_msg_heartbeat_decode(&message, &(current_messages.heartbeat));
234 current_messages.time_stamps.heartbeat = get_time_usec();
235 this_timestamps.heartbeat = current_messages.time_stamps.heartbeat;
239 case MAVLINK_MSG_ID_SYS_STATUS:
242 mavlink_msg_sys_status_decode(&message, &(current_messages.sys_status));
243 current_messages.time_stamps.sys_status = get_time_usec();
244 this_timestamps.sys_status = current_messages.time_stamps.sys_status;
248 case MAVLINK_MSG_ID_BATTERY_STATUS:
251 mavlink_msg_battery_status_decode(&message, &(current_messages.battery_status));
252 current_messages.time_stamps.battery_status = get_time_usec();
253 this_timestamps.battery_status = current_messages.time_stamps.battery_status;
257 case MAVLINK_MSG_ID_RADIO_STATUS:
260 mavlink_msg_radio_status_decode(&message, &(current_messages.radio_status));
261 current_messages.time_stamps.radio_status = get_time_usec();
262 this_timestamps.radio_status = current_messages.time_stamps.radio_status;
266 case MAVLINK_MSG_ID_LOCAL_POSITION_NED:
269 mavlink_msg_local_position_ned_decode(&message, &(current_messages.local_position_ned));
270 current_messages.time_stamps.local_position_ned = get_time_usec();
271 this_timestamps.local_position_ned = current_messages.time_stamps.local_position_ned;
275 case MAVLINK_MSG_ID_GLOBAL_POSITION_INT:
278 mavlink_msg_global_position_int_decode(&message, &(current_messages.global_position_int));
279 current_messages.time_stamps.global_position_int = get_time_usec();
280 this_timestamps.global_position_int = current_messages.time_stamps.global_position_int;
284 case MAVLINK_MSG_ID_POSITION_TARGET_LOCAL_NED:
287 mavlink_msg_position_target_local_ned_decode(&message, &(current_messages.position_target_local_ned));
288 current_messages.time_stamps.position_target_local_ned = get_time_usec();
289 this_timestamps.position_target_local_ned = current_messages.time_stamps.position_target_local_ned;
293 case MAVLINK_MSG_ID_POSITION_TARGET_GLOBAL_INT:
296 mavlink_msg_position_target_global_int_decode(&message, &(current_messages.position_target_global_int));
297 current_messages.time_stamps.position_target_global_int = get_time_usec();
298 this_timestamps.position_target_global_int = current_messages.time_stamps.position_target_global_int;
302 case MAVLINK_MSG_ID_HIGHRES_IMU:
305 mavlink_msg_highres_imu_decode(&message, &(current_messages.highres_imu));
306 current_messages.time_stamps.highres_imu = get_time_usec();
307 this_timestamps.highres_imu = current_messages.time_stamps.highres_imu;
311 case MAVLINK_MSG_ID_ATTITUDE:
314 mavlink_msg_attitude_decode(&message, &(current_messages.attitude));
315 current_messages.time_stamps.attitude = get_time_usec();
316 this_timestamps.attitude = current_messages.time_stamps.attitude;
332 this_timestamps.heartbeat &&
341 this_timestamps.sys_status;
344 if (writing_status >
false)
355int Autopilot_Interface::write_message(mavlink_message_t message)
358 int len = port->write_message(message);
370void Autopilot_Interface::write_setpoint()
377 mavlink_set_position_target_local_ned_t sp;
379 std::lock_guard<std::mutex> lock(current_setpoint.mutex);
380 sp = current_setpoint.data;
385 if (!sp.time_boot_ms)
387 sp.time_boot_ms =
static_cast<uint32_t
>(get_time_usec() / 1000);
389 sp.target_system =
static_cast<uint8_t
>(system_id);
390 sp.target_component =
static_cast<uint8_t
>(autopilot_id);
396 mavlink_message_t message;
397 mavlink_msg_set_position_target_local_ned_encode(
static_cast<uint8_t
>(system_id),
static_cast<uint8_t
>(companion_id), &message, &sp);
404 int len = write_message(message);
409 LOG_WARN(
"autopilot_interface.cpp - could not send POSITION_TARGET_LOCAL_NED \n");
418void Autopilot_Interface::enable_offboard_control()
421 if (!
static_cast<bool>(control_status))
423 LOG_INFO(
"autopilot_interface.cpp - ENABLE OFFBOARD MODE\n");
430 int success = toggle_offboard_control(
true);
435 control_status =
true;
439 LOG_ERROR(
"autopilot_interface.cpp - off-board mode not set, could not write message\n");
449void Autopilot_Interface::disable_offboard_control()
452 if (
static_cast<bool>(control_status))
454 LOG_INFO(
"autopilot_interface.cpp - DISABLE OFFBOARD MODE\n");
461 int success = toggle_offboard_control(
false);
466 control_status =
false;
470 LOG_ERROR(
"autopilot_interface.cpp - off-board mode not set, could not write message\n");
480int Autopilot_Interface::arm_disarm(
bool flag)
484 LOG_INFO(
"autopilot_interface.cpp - ARM ROTORS\n");
488 LOG_INFO(
"autopilot_interface.cpp - DISARM ROTORS\n");
492 mavlink_command_long_t com = { 0, NAN, NAN, NAN, NAN, NAN, NAN, 0, 0, 0, 0 };
493 com.target_system =
static_cast<uint8_t
>(system_id);
494 com.target_component =
static_cast<uint8_t
>(autopilot_id);
495 com.command = MAV_CMD_COMPONENT_ARM_DISARM;
496 com.confirmation =
true;
497 com.param1 =
static_cast<float>(flag);
501 mavlink_message_t message;
502 mavlink_msg_command_long_encode(
static_cast<uint8_t
>(system_id),
static_cast<uint8_t
>(companion_id), &message, &com);
505 int len = port->write_message(message);
514int Autopilot_Interface::toggle_offboard_control(
bool flag)
517 mavlink_command_long_t com = { 0, NAN, NAN, NAN, NAN, NAN, NAN, 0, 0, 0, 0 };
518 com.target_system =
static_cast<uint8_t
>(system_id);
519 com.target_component =
static_cast<uint8_t
>(autopilot_id);
520 com.command = MAV_CMD_NAV_GUIDED_ENABLE;
521 com.confirmation =
true;
522 com.param1 =
static_cast<float>(flag);
525 mavlink_message_t message;
526 mavlink_msg_command_long_encode(
static_cast<uint8_t
>(system_id),
static_cast<uint8_t
>(companion_id), &message, &com);
529 int len = port->write_message(message);
538int Autopilot_Interface::MOCAP_Input(
float w,
float x,
float y,
float z)
540 mavlink_att_pos_mocap_t current_MOCAP{};
542 current_MOCAP.time_usec = get_time_usec();
543 current_MOCAP.q[0] = w;
544 current_MOCAP.q[1] = x;
545 current_MOCAP.q[2] = y;
546 current_MOCAP.q[3] = z;
551 current_MOCAP.covariance[0] = { std::nanf(
"1") };
577 mavlink_message_t message;
578 mavlink_msg_att_pos_mocap_encode(
static_cast<uint8_t
>(system_id),
static_cast<uint8_t
>(companion_id), &message, ¤t_MOCAP);
581 int len = port->write_message(message);
591int Autopilot_Interface::GPS_Input(int32_t lat_d, int32_t lon_d,
float alt,
float vn,
float ve,
float vd, uint32_t time_week_ms, uint16_t time_week)
593 mavlink_gps_input_t
GPS;
594 GPS.time_usec = get_time_usec();
596 GPS.ignore_flags = GPS_INPUT_IGNORE_FLAG_HDOP | GPS_INPUT_IGNORE_FLAG_VDOP |
599 GPS_INPUT_IGNORE_FLAG_SPEED_ACCURACY | GPS_INPUT_IGNORE_FLAG_HORIZONTAL_ACCURACY | GPS_INPUT_IGNORE_FLAG_VERTICAL_ACCURACY;
600 GPS.time_week_ms = time_week_ms;
601 GPS.time_week = time_week;
611 GPS.speed_accuracy = 0.0F;
612 GPS.horiz_accuracy = 0.0F;
613 GPS.vert_accuracy = 0.0F;
614 GPS.satellites_visible = 20;
618 mavlink_message_t message;
619 mavlink_msg_gps_input_encode(
static_cast<uint8_t
>(system_id),
static_cast<uint8_t
>(companion_id), &message, &GPS);
622 int len = port->write_message(message);
631void Autopilot_Interface::setGPS(int32_t lat_d, int32_t lon_d,
float alt,
float vn,
float ve,
float vd, uint32_t time_week_ms, uint16_t time_week)
639 gps_time_week_ms = time_week_ms;
640 gps_time_week = time_week;
646void Autopilot_Interface::setMOCAP(
float w,
float x,
float y,
float z)
657void Autopilot_Interface::setGPS_Active(
bool _Active)
659 GPS_Active = _Active;
665void Autopilot_Interface::setMOCAP_Active(
bool _Active)
667 MOCAP_Active = _Active;
673void Autopilot_Interface::setMOCAP_Frequency(
double _Frequency)
675 MOCAP_Frequency = _Frequency;
681void Autopilot_Interface::setGPS_Frequency(
double _Frequency)
683 GPS_Frequency = _Frequency;
689void Autopilot_Interface::start()
691 std::optional<int> result;
692 time_to_exit =
false;
693 current_messages = {};
698 if (!port->is_running())
700 LOG_ERROR(
"autopilot_interface.cpp - port not open\n");
709 LOG_INFO(
"autopilot_interface.cpp - START READ THREAD \n");
711 result = pthread_create(&read_tid,
nullptr, &start_autopilot_interface_read_thread,
this);
712 if (result.has_value())
723 LOG_INFO(
"autopilot_interface.cpp - CHECK FOR MESSAGES\n");
725 while (!current_messages.sysid)
727 if (time_to_exit || i >= 20)
729 LOG_ERROR(
"autopilot_interface.cpp - NO MESSAGES FOUND\n");
737 LOG_INFO(
"autopilot_interface.cpp - Found\n");
753 system_id = current_messages.sysid;
754 LOG_INFO(
"autopilot_interface.cpp - GOT VEHICLE SYSTEM ID: {}\n", system_id);
760 autopilot_id = current_messages.compid;
761 LOG_INFO(
"autopilot_interface.cpp - GOT AUTOPILOT COMPONENT ID: {}\n", autopilot_id);
780 Mavlink_Messages local_data = current_messages;
781 initial_position.x = local_data.local_position_ned.x;
782 initial_position.y = local_data.local_position_ned.y;
783 initial_position.z = local_data.local_position_ned.z;
784 initial_position.vx = local_data.local_position_ned.vx;
785 initial_position.vy = local_data.local_position_ned.vy;
786 initial_position.vz = local_data.local_position_ned.vz;
787 initial_position.yaw = local_data.attitude.yaw;
788 initial_position.yaw_rate = local_data.attitude.yawspeed;
790 LOG_INFO(
"autopilot_interface.cpp - INITIAL POSITION XYZ = [ {} , {} , {} ] \n", initial_position.x, initial_position.y, initial_position.z);
791 LOG_INFO(
"autopilot_interface.cpp - INITIAL POSITION YAW = {} \n", initial_position.yaw);
798 LOG_INFO(
"autopilot_interface.cpp - START WRITE THREAD \n");
800 result = pthread_create(&write_tid,
nullptr, &start_autopilot_interface_write_thread,
this);
801 if (result.has_value())
807 while (!writing_status)
820void Autopilot_Interface::stop()
825 LOG_INFO(
"autopilot_interface.cpp - CLOSE THREADS\n");
831 pthread_join(read_tid,
nullptr);
832 pthread_join(write_tid,
nullptr);
842void Autopilot_Interface::start_read_thread()
844 if (reading_status != 0)
846 LOG_WARN(
"autopilot_interface.cpp - read thread already running\n");
857void Autopilot_Interface::start_write_thread()
859 if (
static_cast<bool>(writing_status))
861 LOG_ERROR(
"autopilot_interface.cpp - write thread already running\n");
872void Autopilot_Interface::handle_quit(
int )
874 disable_offboard_control();
880 catch (
const std::exception& )
882 LOG_ERROR(
"autopilot_interface.cpp - could not stop autopilot interface\n");
889void Autopilot_Interface::read_thread()
891 reading_status =
true;
893 while (!time_to_exit)
899 reading_status =
false;
905void Autopilot_Interface::write_thread()
927 writing_status =
true;
931 auto lastCallTimeGPS = std::chrono::system_clock::now();
932 auto lastCallTimeMOCAP = std::chrono::system_clock::now();
933 while (!time_to_exit)
935 auto currentTime = std::chrono::system_clock::now();
936 auto elapsedTimeGPS = std::chrono::duration_cast<std::chrono::duration<double>>(currentTime - lastCallTimeGPS).count();
937 auto elapsedTimeMOCAP = std::chrono::duration_cast<std::chrono::duration<double>>(currentTime - lastCallTimeMOCAP).count();
939 if ((GPS_Frequency > 0.0) && (elapsedTimeGPS >= 1.0 / GPS_Frequency))
943 GPS_Input(gps_lat_d, gps_lon_d, gps_alt, gps_vn, gps_ve, gps_vd, gps_time_week_ms, gps_time_week);
945 lastCallTimeGPS = currentTime;
947 if ((MOCAP_Frequency > 0.0) && (elapsedTimeMOCAP >= 1.0 / MOCAP_Frequency))
951 MOCAP_Input(mocap_w, mocap_x, mocap_y, mocap_z);
953 lastCallTimeMOCAP = currentTime;
958 writing_status =
false;
967void* start_autopilot_interface_read_thread(
void* args)
970 auto* autopilot_interface =
static_cast<Autopilot_Interface*
>(args);
973 autopilot_interface->start_read_thread();
979void* start_autopilot_interface_write_thread(
void* args)
982 auto* autopilot_interface =
static_cast<Autopilot_Interface*
>(args);
985 autopilot_interface->start_write_thread();
Utility class for logging to console and file.
#define LOG_ERROR
Error occurred, which stops part of the program to work, but not everything.
#define LOG_WARN
Error occurred, but a fallback option exists and program continues to work normally.
#define LOG_INFO
Info to the user on the state of the program.
Autopilot interface definition.
void stop()
Stops the Thread.
@ GPS
Global Positioning System.