Line data Source code
1 : /* 2 : This program is free software: you can redistribute it and/or modify 3 : it under the terms of the GNU General Public License as published by 4 : the Free Software Foundation, either version 3 of the License, or 5 : (at your option) any later version. 6 : 7 : This program is distributed in the hope that it will be useful, 8 : but WITHOUT ANY WARRANTY; without even the implied warranty of 9 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 : GNU General Public License for more details. 11 : 12 : You should have received a copy of the GNU General Public License 13 : along with this program. If not, see <http://www.gnu.org/licenses/>. 14 : */ 15 : /* 16 : simulator connector for Scrimmage simulator 17 : */ 18 : 19 : #include "SIM_config.h" 20 : 21 : #if AP_SIM_SCRIMMAGE_ENABLED 22 : 23 : #include "SIM_Scrimmage.h" 24 : 25 : #include <stdio.h> 26 : #include <inttypes.h> 27 : #include <sys/stat.h> 28 : #include <sys/types.h> 29 : 30 : #include <AP_HAL/AP_HAL.h> 31 : 32 : extern const AP_HAL::HAL& hal; 33 : 34 : namespace SITL { 35 : 36 0 : Scrimmage::Scrimmage(const char *_frame_str) : 37 : Aircraft(_frame_str), 38 0 : prev_timestamp_us(0), 39 0 : recv_sock(true), 40 0 : send_sock(true) 41 : { 42 0 : } 43 : 44 0 : void Scrimmage::set_interface_ports(const char* address, const int port_in, const int port_out) 45 : { 46 0 : fdm_port_in = port_in; 47 0 : fdm_port_out = port_out; 48 0 : fdm_address = address; 49 0 : printf("ArduPilot sending to scrimmage on %s:%d\n",fdm_address, fdm_port_out); 50 0 : printf("ArduPilot listening to scrimmage on %s:%d\n",fdm_address, fdm_port_in); 51 : 52 0 : recv_sock.bind(fdm_address, fdm_port_in); 53 : 54 0 : recv_sock.reuseaddress(); 55 0 : recv_sock.set_blocking(false); 56 : 57 0 : send_sock.reuseaddress(); 58 0 : send_sock.set_blocking(false); 59 0 : } 60 : 61 0 : void Scrimmage::send_servos(const struct sitl_input &input) 62 : { 63 : servo_packet pkt; 64 : 65 0 : for (int i = 0; i < MAX_NUM_SERVOS; i++) { 66 0 : pkt.servos[i] = input.servos[i]; 67 : } 68 0 : send_sock.sendto(&pkt, sizeof(servo_packet), fdm_address, fdm_port_out); 69 0 : } 70 : 71 : /* 72 : receive an update from the FDM 73 : This is a blocking function 74 : */ 75 0 : void Scrimmage::recv_fdm(const struct sitl_input &input) 76 : { 77 : fdm_packet pkt; 78 : 79 : // wait for packet from scrimmage 80 0 : while (recv_sock.recv(&pkt, sizeof(pkt), 100) != sizeof(pkt)); 81 : 82 : // auto-adjust to simulation frame rate 83 0 : uint64_t dt_us = 0; 84 0 : if (pkt.timestamp_us > prev_timestamp_us) 85 0 : dt_us = pkt.timestamp_us - prev_timestamp_us; 86 0 : time_now_us += dt_us; 87 : 88 0 : float dt_inv = 1.0e6 / ((float)dt_us); 89 0 : if ( dt_inv > 100) { 90 0 : adjust_frame_time(dt_inv); 91 : } 92 0 : prev_timestamp_us = pkt.timestamp_us; 93 : 94 : // dcm_bl: dcm from body to local frame 95 0 : dcm.from_euler(pkt.roll, pkt.pitch, pkt.yaw); 96 0 : dcm.normalize(); 97 : 98 : // subtract gravity to get specific force measuremnt of the IMU 99 0 : accel_body = Vector3f(pkt.xAccel, pkt.yAccel, pkt.zAccel) - dcm.transposed()*Vector3f(0.0f, 0.0f, GRAVITY_MSS); 100 0 : gyro = Vector3f(pkt.rollRate, pkt.pitchRate, pkt.yawRate); 101 : 102 0 : velocity_ef = Vector3f(pkt.speedN, pkt.speedE, pkt.speedD); 103 : 104 0 : location = { 105 0 : int32_t(pkt.latitude * 1.0e7), 106 0 : int32_t(pkt.longitude * 1.0e7), 107 0 : int32_t(pkt.altitude * 1.0e2), 108 : Location::AltFrame::ABSOLUTE 109 : }; 110 0 : UNUSED_RESULT(home.get_height_above(location, position.z)); 111 : 112 : // velocity relative to air mass, in earth frame TODO 113 0 : velocity_air_ef = velocity_ef - wind_ef; 114 : 115 : // velocity relative to airmass in body frame TODO 116 0 : velocity_air_bf = dcm.transposed() * velocity_air_ef; 117 : 118 0 : battery_voltage = 0; 119 0 : battery_current = 0; 120 0 : battery_temperature_degC = 0; 121 0 : rpm[0] = 0; 122 0 : rpm[1] = 0; 123 : 124 0 : airspeed = pkt.airspeed; 125 0 : airspeed_pitot = pkt.airspeed; 126 0 : } 127 : 128 : /* 129 : update the Scrimmage simulation by one time step 130 : */ 131 0 : void Scrimmage::update(const struct sitl_input &input) 132 : { 133 0 : send_servos(input); 134 0 : recv_fdm(input); 135 0 : update_mag_field_bf(); 136 0 : } 137 : 138 : } // namespace SITL 139 : 140 : #endif // AP_SIM_SCRIMMAGE_ENABLED