Files
moos-ivp-pi/src/pEmulator/Emulator.cpp
2023-11-29 14:13:48 +08:00

418 lines
13 KiB
C++
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* @Author: zjk 1553836110@qq.com
* @Date: 2023-10-12 09:52:27
* @LastEditors: zhaojingkui 1553836110@qq.com
* @LastEditTime: 2023-11-28 11:32:48
* @FilePath: /moos-ivp-pi/src/pEmulator/Emulator.cpp
* @Description:
*
* Copyright (c) 2023 by ${git_name_email}, All Rights Reserved.
*/
// #define DEBUG
#include"Emulator.hpp"
#include <exception>
#include"ACTable.h"
bool _ListenCB(void * pParam)
{
Emulator* pMe = (Emulator* )pParam;
return pMe->receiveUdpDate();
}
bool _ListenBSC(void* pParam)
{
_150server* pMe = (_150server*)pParam;
return pMe->listenInfo();
}
bool _Connect(void* pParam)
{
Emulator* pMe = (Emulator* )pParam;
return pMe->_150Connect();
}
bool Emulator::OnNewMail(MOOSMSG_LIST &NewMail)
{
AppCastingMOOSApp::OnNewMail(NewMail);
MOOSMSG_LIST::iterator p;
for(p=NewMail.begin(); p!=NewMail.end(); p++)
{
CMOOSMsg &msg = *p;
string key = msg.m_sKey;
string sval = msg.m_sVal;
double dval = msg.m_dfVal;
double dfT;
msg.IsSkewed(m_curr_time, &dfT);
// if(key == "DESIRED_RUDDER")
// {
// sendBuf[0] = dval;
// remus100.rudder = dval;
// }
// else if(key == "DESIRED_ELEVATOR")
// {
// sendBuf[1] = dval;
// remus100.elevator = dval;
// }
// else if(key == "DESIRED_THRUST")
// {
// sendBuf[2] = dval;
// remus100.thrust = dval;
// }
// else
if(key == "DESIRED_DEPTH")
sendBuf[3] = dval;
else if(key == "DESIRED_HEADING")
sendBuf[4] = dval;
else if(key == "DESIRED_SPEED")
sendBuf[5] = dval;
// reportRunWarning("UnKown var:" + key);
}
return true;
}
bool Emulator::Iterate()
{
AppCastingMOOSApp::Iterate();
if(_150ServerThread.IsThreadRunning())
{ // 这里需要转换数据
if(p_150server_1._150cmd.helm_top_angle > 128)
sendBuf[0] = -(p_150server_1._150cmd.helm_top_angle - 128);
else
sendBuf[0] = p_150server_1._150cmd.helm_top_angle;
if(p_150server_1._150cmd.helm_right_angle > 128)
sendBuf[1] = -(p_150server_1._150cmd.helm_right_angle - 128);
else
sendBuf[1] = p_150server_1._150cmd.helm_right_angle;
sendBuf[2] = (uint8_t)p_150server_1._150cmd.thrust * 1525 / 100;
set150Info();
p_150server_1.postInfo();
isConnect = " 150 Server...";
}
else
isConnect = "No 150 Connect...";
udp->iSendMessageTo((void*)sendBuf, sendBufSize, matalb_port, matlab_host);
//postNodeRecordUpdate(prefix, record);
AppCastingMOOSApp::PostReport();
return true;
}
bool Emulator::OnConnectToServer()
{
registerVariables();
return true;
}
bool Emulator::OnStartUp()
{
AppCastingMOOSApp::OnStartUp();
//TODO: 添加初始状态设置
STRING_LIST sParams;
m_MissionReader.GetConfiguration(GetAppName(), sParams);
STRING_LIST::iterator p;
for(p=sParams.begin(); p!=sParams.end(); p++)
{
bool unhandled = false;
string orig = *p;
string line = *p;
string param = toupper(biteStringX(line, '='));
string value = line;
double dval = atof(value.c_str());
cout << param << endl;
if(param == "MATLAB_HOST")
{
matlab_host = value;
}
else if(param == "MATLAB_PORT")
{
matalb_port = (long int)dval;
}
else if(param == "LOCAL_PORT")
{
local_port = (long int)dval;
}
else if(param == "PREFIX")
{
setNonWhiteVarOnString(prefix, value);
}
else if(param == "START_X")
{
start_x = dval;
}
else if(param == "START_Y")
{
start_y = dval;
}
else if(param == "START_Z")
{
start_z = dval;
}
else if(param == "START_HEADING")
{
start_heading = dval;
}
else
unhandled = true;
if(unhandled)
reportUnhandledConfigWarning(orig);
}
//添加UDP 设置
//TODO添加try
try
{
udp = new XPCUdpSocket(local_port);
udp->vSetBroadcast(true);
udp->vBindSocket();
}
catch(const std::exception& e)
{
std::cerr << e.what() << '\n';
reportRunWarning("Local port Open Field");
}
//初始化数据
receiveBufSize = receiveDateSize*sizeof(double);
receiveBuf = new char[receiveBufSize];
sendBufSize = sendDataSize*sizeof(double);
sendBuf = new double[sendDataSize];
for(int i=0; i<sendDataSize; i++)
sendBuf[i] = 0;
for(int i=0; i<receiveBufSize; i++)
receiveBuf[i] = 0;
// sendBuf[0] = 0.1;
// sendBuf[1] = 0.1;
// sendBuf[2] = 1525;
record.setX(start_x);
record.setY(start_y);
record.setDepth(start_z);
record.setHeading(start_heading);
receiveThread.Initialise(_ListenCB,this);
receiveThread.Start();
_150ConnectThread.Initialise(_Connect, this);
_150ConnectThread.Start();
//启动150 server
//
//
return true;
}
bool Emulator::_150Connect()
{
cout << "Connect ... " << endl;
isConnect = "Connect...";
p_150server_1._150_startServer();
_150ServerThread.Initialise(_ListenBSC,&(this->p_150server_1));
_150ServerThread.Start();
_150ConnectThread.RequestQuit();
isConnect = "Connected and start server";
return true;
}
void Emulator::registerVariables()
{
AppCastingMOOSApp::RegisterVariables();
Register("DESIRED_RUDDER",0);
Register("DESIRED_THRUST",0);
Register("DESIRED_ELEVATOR",0);
Register("DESIRED_DEPTH");
Register("DESIRED_HEADING");
Register("DESIRED_SPEED");
}
bool Emulator::buildReport()
{
// for(int i=0; i<sendDataSize; i++)
// {
// m_msgs << sendBuf[i] << "!#";
// }
m_msgs << "MATLAB : " << matlab_host << " : " << matalb_port << endl;
m_msgs << "LOCAL : " << local_port << endl;
m_msgs << "_150 Connect: " << isConnect << endl;
m_msgs << "_150 Cmd Recive: " << p_150server_1._150_recive << endl;
m_msgs << "=============================================" << endl;
double *s = (double*)receiveBuf;
m_msgs << "DESIRED_RUDDER : " << sendBuf[0] << " (deg)" << endl;
m_msgs << "DESIRED_ELEVATOR : " << sendBuf[1] << " (deg)" << endl;
m_msgs << "DESIRED_THRUST : " << sendBuf[2] << " (rpm)" << endl;
m_msgs << "Pose : " << "[ " << doubleToStringX(s[6],1) << " , " << doubleToStringX(s[7],1) << " ]" << endl;
m_msgs << "Depth : " << doubleToStringX(s[8],1) << " (m)" << endl;
m_msgs << "u : " << doubleToStringX(s[0],2) << " (m/s)" << endl;
m_msgs << "v : " << doubleToStringX(s[1],2) << " (m/s)" << endl;
m_msgs << "w : " << doubleToStringX(s[2],2) << " (m/s)" << endl;
m_msgs << "p : " << doubleToStringX(s[3],1) << " (deg/s)" << endl;
m_msgs << "q : " << doubleToStringX(s[4],1) << " (deg/s)" << endl;
m_msgs << "r : " << doubleToStringX(s[5],1) << " (deg/s)" << endl;
m_msgs << "roll : " << doubleToStringX(s[9],1) << " (deg)" << endl;
m_msgs << "pitch : " << doubleToStringX(s[10],1) << " (deg)" << endl;
m_msgs << "yaw : " << doubleToStringX(s[11],1) << " (deg)" << endl;
m_msgs << "Lat : " << doubleToStringX(s[12],5) << " (du)" << endl;
m_msgs << "Lon : " << doubleToStringX(s[13],5) << " (du)" << endl;
m_msgs << "Alt : " << doubleToStringX(s[14],5) << " (m)" << endl;
return(true);
}
void Emulator::postNodeRecordUpdate(std::string, const NodeRecord& record)
{
double nav_x = record.getX();
double nav_y = record.getY();
Notify(prefix+"_X", nav_x, m_curr_time);
Notify(prefix+"_Y", nav_y, m_curr_time);
if(geoOk) {
double nav_lat = record.getLat();
double nav_lon = record.getLon();
Notify(prefix+"_LAT", nav_lat, m_curr_time);
Notify(prefix+"_LONG", nav_lon, m_curr_time);
}
double new_speed = record.getSpeed();
new_speed = snapToStep(new_speed, 0.01);
Notify(prefix+"_HEADING", record.getHeading(), m_curr_time);
Notify(prefix+"_SPEED", new_speed, m_curr_time);
Notify(prefix+"_DEPTH", record.getDepth(), m_curr_time);
// Added by HS 120124 to make it work ok with iHuxley
// Notify("SIMULATION_MODE","TRUE", m_curr_time);
Notify(prefix+"_Z", -record.getDepth(), m_curr_time);
Notify(prefix+"_PITCH", record.getPitch(), m_curr_time);
Notify(prefix+"_YAW", record.getYaw(), m_curr_time);
Notify("TRUE_X", nav_x, m_curr_time);
Notify("TRUE_Y", nav_y, m_curr_time);
double hog = angle360(record.getHeadingOG());
double sog = record.getSpeedOG();
Notify(prefix+"_HEADING_OVER_GROUND", hog, m_curr_time);
Notify(prefix+"_SPEED_OVER_GROUND", sog, m_curr_time);
if(record.isSetAltitude())
Notify(prefix+"_ALTITUDE", record.getAltitude(), m_curr_time);
}
bool Emulator::receiveUdpDate()
{
double u,v,w;
double U;
while(!receiveThread.IsQuitRequested())
{
int iRx = udp->iRecieveMessage(receiveBuf,receiveBufSize);
if(iRx)
{
for(int i=0; i<receiveDateSize; i++)
{
// MOOSTrace(doubleToString(*((double*)receiveBuf+i))+"\n");
double data = *((double*)receiveBuf+i);
switch (i)
{
case 0: //u
u = data;
remus100.u = u*100;
break;
case 1: //v
// record.set
v = data;
remus100.v = v*100;
break;
case 2: //w
// record
w = data;
remus100.w = w*100;
U = sqrt(u*u + v*v + w*w);
record.setSpeed(U);
break;
case 3: //p
remus100.p = data*100;
break;
case 4: //q
remus100.q = data*100;
break;
case 5: //r
remus100.r = data*100;
break;
case 6: //x
remus100.x = data*100;
record.setY(data);
break;
case 7: //y
remus100.y = data*100;
record.setX(data);
break;
case 8: //z
remus100.z = data*100;
record.setDepth(data);
break;
case 9: //phi
remus100.roll = data*100;
break;
case 10: //theta
remus100.pitch = data*100;
record.setPitch(data);
break;
case 11: //psi
remus100.yaw = data*100;
record.setHeading(data);
break;
case 12:
remus100.lat = data;
record.setLat(data);
break;
case 13:
remus100.lon = data;
record.setLon(data);
break;
case 14:
remus100.alt = data;
break;
default:
break;
}
}
}
}
return true;
}
void Emulator::set150Info()
{
p_150server_1.embeddedInfoSrc.header = 0xEBA1; //0:[0,1]
p_150server_1.embeddedInfoSrc.count = (uint16_t)m_iteration; //2:[2,3]
p_150server_1.embeddedInfoSrc.size = (uint8_t)51; //3:[4]
p_150server_1.embeddedInfoSrc.drive_mode = (uint8_t)0xFF; //4:[5]
p_150server_1.embeddedInfoSrc.height = (uint16_t)(150-remus100.z); //5:[6,7]
p_150server_1.embeddedInfoSrc.depth = (uint16_t)remus100.z; //6:[8,9]
p_150server_1.embeddedInfoSrc.yaw = (uint16_t)remus100.yaw; //7:[10,11]
p_150server_1.embeddedInfoSrc.pitch = (int16_t)remus100.pitch; //8:[12,13]
p_150server_1.embeddedInfoSrc.roll = (int16_t)remus100.roll; //9:[14,15]
p_150server_1.embeddedInfoSrc.ins_vx = (int16_t)remus100.u; //10:[16,17]
p_150server_1.embeddedInfoSrc.ins_vy = (int16_t)remus100.v; //11:[18,19]
p_150server_1.embeddedInfoSrc.ins_vz = (int16_t)remus100.w; //12:[20,21]
p_150server_1.embeddedInfoSrc.lon = (int32_t)(remus100.lon * 1000000); //13:[22,23,24,25]
p_150server_1.embeddedInfoSrc.lat = (int32_t)(remus100.lat * 1000000) ; //14:[26,27,28,29]
p_150server_1.embeddedInfoSrc.alt = (int16_t)(remus100.alt * 100);//15:[30,31]
p_150server_1.embeddedInfoSrc.dvl_vx = (int16_t)remus100.u; //16:[32,33]
p_150server_1.embeddedInfoSrc.dvl_vy = (int16_t)remus100.v; //17:[34,35]
p_150server_1.embeddedInfoSrc.dvl_vz = (int16_t)remus100.w; //18:[36,37]
p_150server_1.embeddedInfoSrc.rpm = (int16_t)remus100.thrust; //19:[38,39]
p_150server_1.embeddedInfoSrc.lightEnable = (uint8_t)0x01; //20:[40]
p_150server_1.embeddedInfoSrc.battery_voltage = (uint16_t)30; //21:[41,42]
p_150server_1.embeddedInfoSrc.battery_level = 60; //22:[43]
p_150server_1.embeddedInfoSrc.battery_temp = 21.3 / 0.1; //23:[44,45]
p_150server_1.embeddedInfoSrc.fault_leakSensor = 0x0; //24:[46,47,48,49]
p_150server_1.embeddedInfoSrc.fault_battery = 0x0; //25:[50]
p_150server_1.embeddedInfoSrc.fault_emergencyBattery = 0x0; //26:[51]
p_150server_1.embeddedInfoSrc.fault_thrust = 0x0; //27:[52]
p_150server_1.embeddedInfoSrc.iridium = 0xFF; //28:[53]
p_150server_1.embeddedInfoSrc.throwing_load = 0xFF; //29:[54]
p_150server_1.embeddedInfoSrc.dvl_status = 0x00; //30:[55]
p_150server_1.embeddedInfoSrc.crc = 0XFF; //31:[56]
p_150server_1.embeddedInfoSrc.footer = 0XEE1A; //32:[57,58]
}