You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
142 lines
3.6 KiB
142 lines
3.6 KiB
/* |
|
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/>. |
|
*/ |
|
/* |
|
Simulator for the RichenPower Hybrid generators |
|
|
|
./Tools/autotest/sim_vehicle.py --gdb --debug -v ArduCopter -A --uartF=sim:richenpower --speedup=1 --console |
|
|
|
param set SERIAL5_PROTOCOL 30 |
|
param set SERIAL5_BAUD 9600 |
|
param set SIM_RICH_ENABLE 1 |
|
param set SERVO8_FUNCTION 42 |
|
param fetch |
|
param set SIM_RICH_CTRL 8 |
|
param set RC9_OPTION 85 |
|
param set GEN_TYPE 3 |
|
|
|
reboot |
|
|
|
graph SERVO_OUTPUT_RAW.servo8_raw |
|
graph RC_CHANNELS.chan9_raw |
|
module load generator |
|
|
|
arm throttle (denied because generator not running) |
|
|
|
./Tools/autotest/autotest.py --gdb --debug build.ArduCopter fly.ArduCopter.RichenPower |
|
|
|
*/ |
|
|
|
#pragma once |
|
|
|
#include <AP_Param/AP_Param.h> |
|
|
|
#include "SITL_Input.h" |
|
|
|
#include "SIM_SerialDevice.h" |
|
|
|
namespace SITL { |
|
|
|
class RichenPower : public SerialDevice { |
|
public: |
|
|
|
RichenPower(); |
|
|
|
// update state |
|
void update(const struct sitl_input &input); |
|
|
|
static const AP_Param::GroupInfo var_info[]; |
|
|
|
private: |
|
|
|
// this is what the generator supplies when running full-tilt but |
|
// with no load |
|
const float base_supply_voltage = 50.0f; |
|
const float max_current = 50.0f; |
|
const uint32_t original_seconds_until_maintenance = 20*60; // 20 minutes |
|
|
|
// They have been... we know that the voltage drops to mid 46v |
|
// typically if gennie stops |
|
// So we set batt fs high 46s |
|
// Gennie keeps batts charged to 49v + typically |
|
|
|
uint32_t last_sent_ms; |
|
|
|
void update_control_pin(const struct sitl_input &input); |
|
void update_send(); |
|
|
|
enum class State { |
|
STOP = 21, |
|
IDLE = 22, |
|
RUN = 23, |
|
STOPPING = 24, // idle cool-down period |
|
}; |
|
State _state = State::STOP; |
|
void set_run_state(State newstate); |
|
|
|
AP_Int8 _enabled; // enable richenpower sim |
|
AP_Int8 _ctrl_pin; |
|
|
|
float _current_rpm; |
|
uint32_t _runtime_ms; |
|
uint32_t _last_runtime_ms; |
|
|
|
float _current_current; |
|
|
|
uint32_t last_rpm_update_ms; |
|
|
|
enum class Errors { |
|
MaintenanceRequired = 0, |
|
}; |
|
|
|
// packet to send: |
|
struct PACKED RichenPacket { |
|
uint8_t magic1; |
|
uint8_t magic2; |
|
uint8_t version_minor; |
|
uint8_t version_major; |
|
uint8_t runtime_minutes; |
|
uint8_t runtime_seconds; |
|
uint16_t runtime_hours; |
|
uint32_t seconds_until_maintenance; |
|
uint16_t errors; |
|
uint16_t rpm; |
|
uint16_t throttle; |
|
uint16_t idle_throttle; |
|
uint16_t output_voltage; |
|
uint16_t output_current; |
|
uint16_t dynamo_current; |
|
uint8_t unknown1; |
|
uint8_t mode; |
|
uint8_t unknown6[38]; // "data"?! |
|
uint16_t checksum; |
|
uint8_t footermagic1; |
|
uint8_t footermagic2; |
|
}; |
|
assert_storage_size<RichenPacket, 70> _assert_storage_size_RichenPacket UNUSED_PRIVATE_MEMBER; |
|
|
|
union RichenUnion { |
|
uint8_t parse_buffer[70]; |
|
uint16_t checksum_buffer[35]; |
|
struct RichenPacket packet; |
|
|
|
void update_checksum(); |
|
}; |
|
RichenUnion u; |
|
|
|
// time we were asked to stop; |
|
uint32_t stop_start_ms; |
|
}; |
|
|
|
}
|
|
|