123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168 |
- /*
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
- This program 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 General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
- /*
- simple vicon simulator class
- XKFR
- */
- #include "SIM_Vicon.h"
- #include <stdio.h>
- #include <unistd.h>
- #include <fcntl.h>
- using namespace SITL;
- #define USE_VISION_POSITION_ESTIMATE 1
- Vicon::Vicon()
- {
- int tmp[2];
- if (pipe(tmp) == -1) {
- AP_HAL::panic("pipe() failed");
- }
- fd_my_end = tmp[1];
- fd_their_end = tmp[0];
- // close file descriptors on exec:
- fcntl(fd_my_end, F_SETFD, FD_CLOEXEC);
- fcntl(fd_their_end, F_SETFD, FD_CLOEXEC);
- // make sure we don't screw the simulation up by blocking:
- fcntl(fd_my_end, F_SETFL, fcntl(fd_my_end, F_GETFL, 0) | O_NONBLOCK);
- fcntl(fd_their_end, F_SETFL, fcntl(fd_their_end, F_GETFL, 0) | O_NONBLOCK);
- if (!valid_channel(mavlink_ch)) {
- AP_HAL::panic("Invalid mavlink channel");
- }
- }
- void Vicon::maybe_send_heartbeat()
- {
- const uint32_t now = AP_HAL::millis();
- if (now - last_heartbeat_ms < 100) {
- // we only provide a heartbeat every so often
- return;
- }
- last_heartbeat_ms = now;
- mavlink_message_t msg;
- mavlink_msg_heartbeat_pack(system_id,
- component_id,
- &msg,
- MAV_TYPE_GCS,
- MAV_AUTOPILOT_INVALID,
- 0,
- 0,
- 0);
- }
- void Vicon::update_vicon_position_estimate(const Location &loc,
- const Vector3f &position,
- const Quaternion &attitude)
- {
- const uint64_t now_us = AP_HAL::micros64();
- if (time_offset_us == 0) {
- time_offset_us = (unsigned(random()) % 7000) * 1000000ULL;
- printf("time_offset_us %llu\n", (long long unsigned)time_offset_us);
- }
-
- if (time_send_us && now_us >= time_send_us) {
- uint8_t msgbuf[300];
- uint16_t msgbuf_len = mavlink_msg_to_send_buffer(msgbuf, &obs_msg);
- if (::write(fd_my_end, (void*)&msgbuf, msgbuf_len) != msgbuf_len) {
- ::fprintf(stderr, "Vicon: write failure\n");
- }
- time_send_us = 0;
- }
- if (time_send_us != 0) {
- // waiting for the last msg to go out
- return;
- }
- if (now_us - last_observation_usec < 70000) {
- // create observations at 70ms intervals (matches EK2 max rate)
- return;
- }
- float roll;
- float pitch;
- float yaw;
- attitude.to_euler(roll, pitch, yaw);
- #if USE_VISION_POSITION_ESTIMATE
- // use the more recent VISION_POSITION_ESTIMATE message
- mavlink_msg_vision_position_estimate_pack_chan(
- system_id,
- component_id,
- mavlink_ch,
- &obs_msg,
- now_us + time_offset_us,
- position.x,
- position.y,
- position.z,
- roll,
- pitch,
- yaw,
- NULL, 0);
- #else
- mavlink_msg_vicon_position_estimate_pack_chan(
- system_id,
- component_id,
- mavlink_ch,
- &obs_msg,
- now_us + time_offset_us,
- position.x,
- position.y,
- position.z,
- roll,
- pitch,
- yaw,
- NULL);
- #endif // USE_VISION_POSITION_ESTIMATE
- uint32_t delay_ms = 25 + unsigned(random()) % 300;
- time_send_us = now_us + delay_ms * 1000UL;
- }
- bool Vicon::init_sitl_pointer()
- {
- if (_sitl == nullptr) {
- _sitl = AP::sitl();
- if (_sitl == nullptr) {
- return false;
- }
- }
- return true;
- }
- /*
- update vicon sensor state
- */
- void Vicon::update(const Location &loc, const Vector3f &position, const Quaternion &attitude)
- {
- if (!init_sitl_pointer()) {
- return;
- }
- maybe_send_heartbeat();
- update_vicon_position_estimate(loc, position, attitude);
- }
|