COSMOS core  1.0.2 (beta)
Comprehensive Open-architecture Solution for Mission Operations Systems
agent_control.cpp File Reference

Agent Control for Satellite Ground Station. More...

Include dependency graph for agent_control.cpp:

Classes

struct  radiostruc
 
struct  trackstruc
 
struct  antennastruc
 

Functions

int32_t request_debug (string &request, string &response, Agent *)
 
int32_t request_get_state (string &request, string &response, Agent *)
 
int32_t request_list_tracks (string &request, string &response, Agent *)
 
int32_t request_set_track (string &request, string &response, Agent *)
 
int32_t request_get_track (string &request, string &response, Agent *)
 
int32_t request_list_radios (string &request, string &response, Agent *)
 
int32_t request_match_radio (string &request, string &response, Agent *)
 
int32_t request_list_antennas (string &request, string &response, Agent *)
 
int32_t request_get_highest (string &req, string &response, Agent *)
 
int32_t request_unmatch_radio (string &request, string &response, Agent *)
 
void monitor ()
 
string opmode2string (uint8_t opmode)
 
int main (int argc, char *argv[])
 

Variables

static string nodename = ""
 
static string agentname = "control"
 
static string trajectoryname = ""
 
static Agentagent
 
static mutex cdata_mutex
 
static vector< double > lastantutc
 
static vector< double > lasttcvutc
 
static bool trackinit = true
 
static vector< radiostrucmyradios
 
static size_t trackindex = 9999
 
static size_t highestindex = 9999
 
static float highestvalue = -DPI2
 
static vector< trackstructrack
 
static vector< antennastrucmyantennas
 
static bool debug
 

Detailed Description

Agent Control for Satellite Ground Station.

This is the main agent that controls the ground station. It it the channel for the T&C and it is also responsible for the Agent Antenna and Agent Radio

Function Documentation

int32_t request_debug ( string &  request,
string &  response,
Agent  
)
937 {
938  if (debug)
939  {
940  debug = false;
941  }
942  else
943  {
944  debug = true;
945  }
946 
947  return 0;
948 }
static bool debug
Definition: agent_control.cpp:185
int32_t request_get_state ( string &  request,
string &  response,
Agent  
)
888 {
889  if (trackindex == 0)
890  {
891  response = '[' + to_mjd(currentmjd()) + "] 0: idle [0.D 0.D] ";
892  }
893  else
894  {
895  response = '[' + to_mjd(currentmjd()) + "] ";
896  response += track[trackindex].name + '(';
897  response += to_unsigned(trackindex) + ") ";
898  response += '[' + to_angle(fixangle(track[trackindex].target.azfrom), 'D', 5) + ' ';
899  response += to_angle(track[trackindex].target.elfrom, 'D', 4) + "] ";
900  }
901  for (size_t i=0; i<myradios.size(); ++i)
902  {
903  if (myradios[i].otherradioindex != 9999)
904  {
905  size_t idx = myradios[i].otherradioindex;
906  response += "{ ";
907  response += to_label("GS", myradios[i].name) + ' ';
908  response += to_label("Sat", track[trackindex].radios[idx].name) + ' ';
909  response += to_label("Freq", myradios[i].info.freq, 9) + " (" + to_double(myradios[i].dfreq, 5) + ") } ";
910  }
911  else {
912  response += "{ ";
913  response += to_label("GS", myradios[i].name) + ' ';
914  response += to_label("Freq", myradios[i].info.freq, 9) + " (" + to_double(myradios[i].dfreq, 5) + ") } ";
915  }
916  }
917  for (size_t i=0; i<myantennas.size(); ++i)
918  {
919  if (86400. * (currentmjd() - myantennas[i].beat.utc) < 1.)
920  {
921  response += '{' + myantennas[i].name + "} ";
922  }
923  }
924  return (0);
925 }
int i
Definition: rw_test.cpp:37
static antstruc target
Definition: agent_antenna.cpp:160
string to_unsigned(uint64_t value, uint16_t digits, bool zerofill)
Definition: stringlib.cpp:265
static vector< antennastruc > myantennas
Definition: agent_control.cpp:183
static vector< trackstruc > track
Definition: agent_control.cpp:175
string name
Definition: cubesat2obj.cpp:6
double fixangle(double angle)
Limit angle to range 0-2PI.
Definition: mathlib.cpp:2159
double currentmjd(double offset)
Current UTC in Modified Julian Days.
Definition: timelib.cpp:65
backing_store_ptr info
Definition: jmemsys.h:181
static size_t trackindex
Definition: agent_control.cpp:162
string to_label(string label, double value, uint16_t precision, bool mjd)
Definition: stringlib.cpp:376
static vector< radiostruc > myradios
Definition: agent_control.cpp:160
string to_mjd(double value)
Definition: stringlib.cpp:298
string to_angle(double value, char units, uint8_t precision)
Definition: stringlib.cpp:313
string to_double(double value, uint16_t precision)
Definition: stringlib.cpp:285
int32_t request_list_tracks ( string &  request,
string &  response,
Agent  
)
689 {
690  response.clear();
691  for (size_t i=0; i<track.size(); ++i)
692  {
693  response += '\n' + track[i].name + ' ' + to_angle(DPI2-track[i].target.elfrom, 'D');
694  }
695  response += '\n';
696 
697  return 0;
698 }
int i
Definition: rw_test.cpp:37
static antstruc target
Definition: agent_antenna.cpp:160
const double DPI2
Double precision PI/2.
Definition: math/constants.h:18
static vector< trackstruc > track
Definition: agent_control.cpp:175
string to_angle(double value, char units, uint8_t precision)
Definition: stringlib.cpp:313
int32_t request_set_track ( string &  request,
string &  response,
Agent  
)
701 {
702  size_t tracki;
703 
704  switch (request[10])
705  {
706  case '0':
707  case '1':
708  case '2':
709  case '3':
710  case '4':
711  case '5':
712  case '6':
713  case '7':
714  case '8':
715  case '9':
716  sscanf(request.c_str(), "set_track %lu", &tracki);
717  if (tracki < track.size())
718  {
719  trackindex = tracki;
720  }
721  break;
722  default:
723  char trackname[41];
724  sscanf(request.c_str(), "set_track %40s", trackname);
725  for (tracki=0; tracki<track.size(); ++tracki)
726  {
727  if (!strcmp(track[tracki].name.c_str(), trackname))
728  {
729  trackindex = tracki;
730  break;
731  }
732  }
733  break;
734  }
735 
736  for (size_t i=0; i<myradios.size(); ++i)
737  {
738  myradios[i].otherradioindex = 9999;
739  }
740 
741  for (size_t i=0; i<track[trackindex].radios.size(); ++i)
742  {
743  track[trackindex].radios[i].otherradioindex = 9999;
744  }
745 
746  trackinit = true;
747 
748  return 0;
749 }
int i
Definition: rw_test.cpp:37
static bool trackinit
Definition: agent_control.cpp:147
static vector< trackstruc > track
Definition: agent_control.cpp:175
string name
Definition: cubesat2obj.cpp:6
static size_t trackindex
Definition: agent_control.cpp:162
static vector< radiostruc > myradios
Definition: agent_control.cpp:160
int32_t request_get_track ( string &  request,
string &  response,
Agent  
)
752 {
753  if (trackindex != 9999)
754  {
755  response = to_unsigned(trackindex) + ' ' + track[trackindex].name + ' ' + to_double(track[trackindex].target.range) + ' ' + to_double(track[trackindex].target.range/track[trackindex].target.close);
756  }
757 
758  return 0;
759 }
static antstruc target
Definition: agent_antenna.cpp:160
string to_unsigned(uint64_t value, uint16_t digits, bool zerofill)
Definition: stringlib.cpp:265
static vector< trackstruc > track
Definition: agent_control.cpp:175
static size_t trackindex
Definition: agent_control.cpp:162
string to_double(double value, uint16_t precision)
Definition: stringlib.cpp:285
int32_t request_list_radios ( string &  request,
string &  response,
Agent  
)
762 {
763  response = ("My Radios");
764  for (size_t i=0; i<myradios.size(); ++i)
765  {
766  response += '\n' + to_signed(i) + ' ' + to_label("Name", myradios[i].name) + ' ' + to_label("OtherIndex", myradios[i].otherradioindex) + ' ' + to_label("Freq", myradios[i].info.freq, 9) + ' ' + to_label("Opmode", opmode2string(myradios[i].info.opmode));
767  }
768 
769  response += ("\nOther Radios");
770  for (size_t i=0; i<track[trackindex].radios.size(); ++i)
771  {
772  response += '\n' + to_signed(i) + ' ' + to_label("Name", track[trackindex].radios[i].name) + ' ' + to_label("MyIndex", track[trackindex].radios[i].otherradioindex) + ' ' + to_label("Freq", track[trackindex].radios[i].info.freq, 9) + ' ' + to_label("Opmode", opmode2string(track[trackindex].radios[i].info.opmode));
773  }
774 
775  return 0;
776 }
int i
Definition: rw_test.cpp:37
string opmode2string(uint8_t opmode)
Definition: agent_control.cpp:950
string to_signed(int64_t value, uint16_t digits, bool zerofill)
Definition: stringlib.cpp:245
static vector< trackstruc > track
Definition: agent_control.cpp:175
string name
Definition: cubesat2obj.cpp:6
backing_store_ptr info
Definition: jmemsys.h:181
static size_t trackindex
Definition: agent_control.cpp:162
string to_label(string label, double value, uint16_t precision, bool mjd)
Definition: stringlib.cpp:376
static vector< radiostruc > myradios
Definition: agent_control.cpp:160
int32_t request_match_radio ( string &  request,
string &  response,
Agent  
)
779 {
780  string fromname;
781  string toname;
782  uint16_t fromi = 9999;
783  uint16_t toi = 9999;
784 
785  size_t firstspace = request.find(' ');
786  size_t lastspace = request.find_last_of(' ');
787 
788  fromname = request.substr(firstspace+1, (lastspace-firstspace)-1);
789  toname = request.substr(lastspace+1);
790 
791  if (fromname[0] < '0' && fromname[0] > '9')
792  {
793  for (fromi=0; fromi<myradios.size(); ++fromi)
794  {
795  if (myradios[fromi].name == fromname)
796  {
797  break;
798  }
799  }
800  }
801  else
802  {
803  fromi = stoi(fromname);
804  }
805 
806  if (toname[0] < '0' && toname[0] > '9')
807  {
808  for (toi=0; toi<myradios.size(); ++toi)
809  {
810  if (myradios[toi].name == toname)
811  {
812  break;
813  }
814  }
815  }
816  else
817  {
818  toi = stoi(toname);
819  }
820 
821  if (fromi < myradios.size() && toi < track[trackindex].radios.size())
822  {
823  myradios[fromi].otherradioindex = toi;
824  track[trackindex].radios[toi].otherradioindex = fromi;
825  response = ("Matched " + myradios[fromi].name + " to " + track[trackindex].radios[toi].name);
826  }
827  else
828  {
829  response = ("No match");
830  }
831 
832  return 0;
833 }
static vector< trackstruc > track
Definition: agent_control.cpp:175
string name
Definition: cubesat2obj.cpp:6
static size_t trackindex
Definition: agent_control.cpp:162
static vector< radiostruc > myradios
Definition: agent_control.cpp:160
int32_t request_list_antennas ( string &  request,
string &  response,
Agent  
)
878 {
879  for (size_t i=0; i<myantennas.size(); ++i)
880  {
881  response += std::to_string(i) + " " + myantennas[i].name + " " + std::to_string(myantennas[i].info.minelev) + "\n";
882  }
883 
884  return 0;
885 }
int i
Definition: rw_test.cpp:37
string to_string(char *value)
Definition: stringlib.cpp:220
static vector< antennastruc > myantennas
Definition: agent_control.cpp:183
backing_store_ptr info
Definition: jmemsys.h:181
int32_t request_get_highest ( string &  req,
string &  response,
Agent  
)
928 {
929  if (highestindex != 9999)
930  {
931  response = to_unsigned(highestindex) + ": " + track[highestindex].name + " [" + to_angle(fixangle(track[highestindex].target.azfrom), 'D', 1) + ' ' + to_angle(track[highestindex].target.elfrom, 'D', 1) + ']';
932  }
933  return 0;
934 }
static antstruc target
Definition: agent_antenna.cpp:160
string to_unsigned(uint64_t value, uint16_t digits, bool zerofill)
Definition: stringlib.cpp:265
static vector< trackstruc > track
Definition: agent_control.cpp:175
double fixangle(double angle)
Limit angle to range 0-2PI.
Definition: mathlib.cpp:2159
static size_t highestindex
Definition: agent_control.cpp:163
string to_angle(double value, char units, uint8_t precision)
Definition: stringlib.cpp:313
int32_t request_unmatch_radio ( string &  request,
string &  response,
Agent  
)
836 {
837  char fromname[41];
838  uint16_t fromi = 9999;
839  uint16_t toi = 9999;
840 
841  sscanf(request.c_str(), "unmatch_radio %40s", fromname);
842 
843  if (fromname[0] < '0' && fromname[0] > '9')
844  {
845  for (fromi=0; fromi<myradios.size(); ++fromi)
846  {
847  if (!strcmp(myradios[fromi].name.c_str(), fromname))
848  {
849  break;
850  }
851  }
852  }
853  else
854  {
855  fromi = atoi(fromname);
856  }
857 
858 
859  if (fromi < myradios.size())
860  {
861  toi = myradios[fromi].otherradioindex;
862  myradios[fromi].otherradioindex = 9999;
863  if (toi < track[trackindex].radios.size())
864  {
865  track[trackindex].radios[toi].otherradioindex = 9999;
866  }
867  response = "Unatched " + myradios[fromi].name + " to " + track[trackindex].radios[toi].name;
868  }
869  else
870  {
871  response = "No match";
872  }
873 
874  return 0;
875 }
static vector< trackstruc > track
Definition: agent_control.cpp:175
string name
Definition: cubesat2obj.cpp:6
static size_t trackindex
Definition: agent_control.cpp:162
static vector< radiostruc > myradios
Definition: agent_control.cpp:160
void monitor ( )
650 {
652 
653  while (agent->running())
654  {
655  Agent::messstruc mess;
656 
657  iretn = (Agent::AgentMessage)agent->readring(mess, Agent::AgentMessage::BEAT, 5.0);
658 
659  // Only process if this is a heartbeat message for our node
660  if (iretn == Agent::AgentMessage::BEAT && !strcmp(mess.meta.beat.node, agent->cinfo->node.name))
661  {
662  cdata_mutex.lock();
663  // Extract telemetry
664  json_parse(mess.adata, agent->cinfo);
665 
666  // Extract agent information
667  for (size_t i=0; i<myantennas.size(); ++i)
668  {
669  if (!strcmp(mess.meta.beat.proc, myantennas[i].name.c_str()))
670  {
671  myantennas[i].beat = mess.meta.beat;
672  }
673  }
674  for (size_t i=0; i<myradios.size(); ++i)
675  {
676  if (!strcmp(mess.meta.beat.proc, myradios[i].name.c_str()))
677  {
678  myradios[i].beat = mess.meta.beat;
679  }
680  }
681  cdata_mutex.unlock();
682 
683  }
684  }
685 
686 }
AgentMessage
Type of Agent Message. Types > 127 are binary.
Definition: agentclass.h:216
beatstruc beat
Definition: agentclass.h:268
static Agent * agent
Definition: agent_control.cpp:142
int i
Definition: rw_test.cpp:37
int32_t json_parse(string jstring, cosmosstruc *cinfo)
Parse JSON using Name Space.
Definition: jsonlib.cpp:4799
int iretn
Definition: rw_test.cpp:37
string adata
Definition: agentclass.h:276
nodestruc node
Structure for summary information in node.
Definition: jsondef.h:4220
uint16_t running()
Check if we&#39;re supposed to be running.
Definition: agentclass.cpp:391
char proc[40+1]
Heartbeat Agent Name.
Definition: jsondef.h:930
char node[40+1]
Definition: jsondef.h:928
static vector< antennastruc > myantennas
Definition: agent_control.cpp:183
char name[40+1]
Node Name.
Definition: jsondef.h:3556
Storage for messages.
Definition: agentclass.h:272
pollstruc meta
Definition: agentclass.h:274
cosmosstruc * cinfo
Definition: agentclass.h:346
static mutex cdata_mutex
Definition: agent_control.cpp:143
static vector< radiostruc > myradios
Definition: agent_control.cpp:160
int32_t readring(messstruc &message, AgentMessage type=Agent::AgentMessage::ALL, float waitsec=1., Where where=Where::TAIL, string proc="", string node="")
Check Ring for message.
Definition: agentclass.cpp:2395
string opmode2string ( uint8_t  opmode)
951 {
952  string result;
953  switch (opmode)
954  {
956  result = "AM";
957  break;
959  result = "AM Data";
960  break;
962  result = "FM";
963  break;
965  result = "FM Data";
966  break;
968  result = "LSB";
969  break;
971  result = "LSB Data";
972  break;
974  result = "USB";
975  break;
977  result = "USB Data";
978  break;
980  result = "RTTY";
981  break;
983  result = "RTTYR";
984  break;
986  result = "DV";
987  break;
989  result = "DV Data";
990  break;
992  result = "CWR";
993  break;
995  result = "CW";
996  break;
997  }
998  return result;
999 }
Definition: jsondef.h:575
Definition: jsondef.h:585
Definition: jsondef.h:584
Definition: jsondef.h:581
Definition: jsondef.h:574
Definition: jsondef.h:576
Definition: jsondef.h:579
Definition: jsondef.h:572
Definition: jsondef.h:583
Definition: jsondef.h:580
static uint8_t opmode
Definition: add_radio.cpp:23
Definition: jsondef.h:582
Definition: jsondef.h:573
Definition: jsondef.h:578
Definition: jsondef.h:577
int main ( int  argc,
char *  argv[] 
)
202 {
203  int32_t iretn;
204 
205  switch (argc)
206  {
207  case 3:
208  nodename = argv[2];
209  case 2:
210  trajectoryname = argv[1];
211  case 1:
212  break;
213  default:
214  printf("Usage: agent->control {nodename}");
215  exit (1);
216  break;
217  }
218 
219  // Establish the command channel and heartbeat
220  if (nodename.empty())
221  {
222  agent = new Agent("", agentname, 5.);
223  }
224  else
225  {
226  agent = new Agent(nodename, agentname, 5.);
227  }
228 
229  if ((iretn = agent->wait()) < 0)
230  {
231  fprintf(agent->get_debug_fd(), "%16.10f %s Failed to start Agent %s on Node %s Dated %s : %s\n",currentmjd(), mjd2iso8601(currentmjd()).c_str(), agent->getAgent().c_str(), agent->getNode().c_str(), utc2iso8601(data_ctime(argv[0])).c_str(), cosmos_error_string(iretn).c_str());
232  exit(iretn);
233  }
234  else
235  {
236  fprintf(agent->get_debug_fd(), "%16.10f %s Started Agent %s on Node %s Dated %s\n",currentmjd(), mjd2iso8601(currentmjd()).c_str(), agent->getAgent().c_str(), agent->getNode().c_str(), utc2iso8601(data_ctime(argv[0])).c_str());
237  }
238 
239  // Build up table of our radios
240  radiostruc tradio;
241  tradio.name = "Direct";
242  tradio.info.freq = 0.;
243  tradio.info.opmode = static_cast<uint16_t>(DEVICE_RADIO_MODE_FMD);
244  tradio.otherradioindex = 9999;
245  tradio.beat.utc = 0.;
246  tradio.basefreq = 0.;
247  tradio.baseopmode = 0;
248  myradios.push_back(tradio);
249  for (size_t i=0; i<agent->cinfo->devspec.tcv_cnt; ++i)
250  {
251  tradio.name = agent->cinfo->pieces[agent->cinfo->device[agent->cinfo->devspec.tcv[i]].pidx].name;
252  tradio.type = DeviceType::TCV;
253  tradio.info = agent->cinfo->device[agent->cinfo->devspec.tcv[i]].tcv;
254  tradio.basefreq = tradio.info.freq;
255  tradio.baseopmode = tradio.info.opmode;
256  tradio.otherradioindex = 9999;
257  tradio.beat = agent->find_agent(nodename, tradio.name, 3.);
258  myradios.push_back(tradio);
259  }
260  for (size_t i=0; i<agent->cinfo->devspec.rxr_cnt; ++i)
261  {
262  tradio.name = agent->cinfo->pieces[agent->cinfo->device[agent->cinfo->devspec.rxr[i]].pidx].name;
263  tradio.type = DeviceType::RXR;
264  tradio.info = agent->cinfo->device[agent->cinfo->devspec.rxr[i]].tcv;
265  tradio.basefreq = tradio.info.freq;
266  tradio.baseopmode = tradio.info.opmode;
267  tradio.otherradioindex = 9999;
268  tradio.beat = agent->find_agent(nodename, tradio.name, 3.);
269  myradios.push_back(tradio);
270  }
271  for (size_t i=0; i<agent->cinfo->devspec.txr_cnt; ++i)
272  {
273  tradio.name = agent->cinfo->pieces[agent->cinfo->device[agent->cinfo->devspec.txr[i]].pidx].name;
274  tradio.type = DeviceType::TXR;
275  tradio.info = agent->cinfo->device[agent->cinfo->devspec.txr[i]].tcv;
276  tradio.basefreq = tradio.info.freq;
277  tradio.baseopmode = tradio.info.opmode;
278  tradio.otherradioindex = 9999;
279  tradio.beat = agent->find_agent(nodename, tradio.name, 3.);
280  myradios.push_back(tradio);
281  }
282 
283  // Build up table of our antennas
285  for (size_t i=0; i<myantennas.size(); ++i)
286  {
287  myantennas[i].name = agent->cinfo->pieces[agent->cinfo->device[agent->cinfo->devspec.ant[i]].pidx].name;
288  myantennas[i].info = agent->cinfo->device[agent->cinfo->devspec.ant[i]].ant;
290  }
291 
292  // Build up table of other nodes. Look through node directory and choose any valid node that
293  // is a satellite or a celestial object. First entry is null, none tracking.
294  track.resize(1);
295  trackindex = 0;
296  track[0].name = "idle";
297  track[0].target.type = NODE_TYPE_DATA;
298  vector <string> nodes;
299  iretn = data_list_nodes(nodes);
300  for (size_t i=0; i<nodes.size(); ++i)
301  {
302  string path = data_base_path(nodes[i]) + "/node.ini";
303  FILE *fp = fopen(path.c_str(), "r");
304  if (fp != nullptr)
305  {
306  int32_t type;
307  fscanf(fp, "{\"node_type\":%d", &type);
308  fclose(fp);
309  switch (type)
310  {
311  case NODE_TYPE_SATELLITE:
312  case NODE_TYPE_SUN:
313  case NODE_TYPE_MOON:
314  trackstruc ttrack;
315  ttrack.name = nodes[i];
316  cosmosstruc *cinfo = json_init();
317  iretn = json_setup_node(ttrack.name, cinfo);
318  if (iretn == 0 && (currentmjd()-cinfo->node.loc.pos.eci.utc) < 10.)
319  {
320  // Valid node. Initialize tracking and push it to list
321  ttrack.target.type = cinfo->node.type;
322  ttrack.target.loc = cinfo->node.loc;
323  ttrack.physics = cinfo->node.phys;
324 
325  // Build up table of radios
326  for (size_t i=0; i<cinfo->devspec.tcv_cnt; ++i)
327  {
328  tradio.name = cinfo->pieces[cinfo->device[cinfo->devspec.tcv[i]].pidx].name;
329  tradio.type = DeviceType::TCV;
330  tradio.info = cinfo->device[cinfo->devspec.tcv[i]].tcv;
331  tradio.otherradioindex = 9999;
332  ttrack.radios.push_back(tradio);
333  }
334 
335  for (size_t i=0; i<cinfo->devspec.txr_cnt; ++i)
336  {
337  tradio.name = cinfo->pieces[cinfo->device[cinfo->devspec.txr[i]].pidx].name;
338  tradio.type = DeviceType::TXR;
339  tradio.info.band = cinfo->device[cinfo->devspec.txr[i]].txr.band;
340  tradio.info.freq = cinfo->device[cinfo->devspec.txr[i]].txr.freq;
341  tradio.info.opmode = cinfo->device[cinfo->devspec.txr[i]].txr.opmode;
342  tradio.info.modulation = cinfo->device[cinfo->devspec.txr[i]].txr.modulation;
343  tradio.otherradioindex = 9999;
344  ttrack.radios.push_back(tradio);
345  }
346 
347  for (size_t i=0; i<cinfo->devspec.rxr_cnt; ++i)
348  {
349  tradio.name = cinfo->pieces[cinfo->device[cinfo->devspec.rxr[i]].pidx].name;
350  tradio.type = DeviceType::RXR;
351  tradio.info.band = cinfo->device[cinfo->devspec.rxr[i]].rxr.band;
352  tradio.info.freq = cinfo->device[cinfo->devspec.rxr[i]].rxr.freq;
353  tradio.info.opmode = cinfo->device[cinfo->devspec.rxr[i]].rxr.opmode;
354  tradio.info.modulation = cinfo->device[cinfo->devspec.rxr[i]].rxr.modulation;
355  tradio.otherradioindex = 9999;
356  ttrack.radios.push_back(tradio);
357  }
358 
359  if (type == NODE_TYPE_SATELLITE)
360  {
361  printf("Propagating Node %s forward %.0f\r", ttrack.name.c_str(), 86400.*(currentmjd()-ttrack.target.loc.pos.eci.utc));
362  gauss_jackson_init_eci(ttrack.gjh, 12, 0, 5., ttrack.target.loc.pos.eci.utc, ttrack.target.loc.pos.eci, ttrack.target.loc.att.icrf, ttrack.physics, ttrack.target.loc);
363  double tutc = ttrack.target.loc.pos.eci.utc + 60./86400.;
364  while (tutc < currentmjd())
365  {
366  printf("Propagating Node %s forward %.0f\r", ttrack.name.c_str(), 86400.*(currentmjd()-ttrack.target.loc.pos.eci.utc));
367  gauss_jackson_propagate(ttrack.gjh, ttrack.physics, ttrack.target.loc, tutc);
368  fflush(stdout);
369  tutc += 600./86400.;
370  }
371  printf("Propagating Node %s forward %.0f\n", ttrack.name.c_str(), 86400.*(currentmjd()-ttrack.target.loc.pos.eci.utc));
372  gauss_jackson_init_eci(ttrack.gjh, 12, 0, 1., ttrack.target.loc.pos.eci.utc, ttrack.target.loc.pos.eci, ttrack.target.loc.att.icrf, ttrack.physics, ttrack.target.loc);
373  gauss_jackson_propagate(ttrack.gjh, ttrack.physics, ttrack.target.loc, currentmjd());
374  fflush(stdout);
375  }
376  track.push_back(ttrack);
377  json_destroy(cinfo);
378  }
379  }
380  }
381  }
382 
383  // Look for TLE file
384  char fname[200];
385  sprintf(fname,"%s/tle.ini",get_nodedir(nodename).c_str());
386  vector <tlestruc> tle;
387  if ((iretn=load_lines_multi(fname, tle)) > 0)
388  {
389  for (size_t i=0; i<tle.size(); ++i)
390  {
391  // Valid node. Initialize tracking and push it to list
392  trackstruc ttrack;
393  ttrack.type = 0;
394  ttrack.name = tle[i].name;
396  tle2eci(currentmjd()-10./86400., tle[i], ttrack.target.loc.pos.eci);
397  ttrack.target.loc.att.icrf.s = q_eye();
398  ttrack.target.loc.att.icrf.v = rv_zero();
399  ttrack.target.loc.att.icrf.a = rv_zero();
400  ttrack.physics.area = .01;
401  ttrack.physics.mass = 1.;
402 
403  // Build up table of radios
404  ttrack.radios.resize(1);
405  ttrack.radios[0].name = "radio";
406  ttrack.radios[0].otherradioindex = 9999;
407 
408  gauss_jackson_init_eci(ttrack.gjh, 6, 0, 1., ttrack.target.loc.pos.eci.utc, ttrack.target.loc.pos.eci, ttrack.target.loc.att.icrf, ttrack.physics, ttrack.target.loc);
409  gauss_jackson_propagate(ttrack.gjh, ttrack.physics, ttrack.target.loc, currentmjd());
410  track.push_back(ttrack);
411  }
412  }
413 
414  struct gentry
415  {
416  double second;
417  gvector geod;
418  rvector geoc;
419  };
420  vector <gentry> trajectory;
421 
422  if (!trajectoryname.empty() && data_isfile(trajectoryname))
423  {
424  FILE *fp = fopen(trajectoryname.c_str(), "r");
425  if (fp != nullptr)
426  {
427  while (!feof(fp))
428  {
429  gentry tentry;
430  iretn = fscanf(fp, "%lf %lf %lf %lf\n", &tentry.second, &tentry.geod.lat, &tentry.geod.lon, &tentry.geod.h);
431  if (iretn == 4)
432  {
433  trajectory.push_back(tentry);
434  }
435  }
436  fclose(fp);
437  if (trajectory.size() > 2)
438  {
439  trackstruc ttrack;
440  ttrack.type = 0;
441  ttrack.name = trajectoryname;
443  ttrack.target.loc.att.icrf.s = q_eye();
444  ttrack.target.loc.att.icrf.v = rv_zero();
445  ttrack.target.loc.att.icrf.a = rv_zero();
446  ttrack.physics.area = .01;
447  ttrack.physics.mass = 1.;
448 
449  // Build up table of radios
450  ttrack.radios.resize(1);
451  ttrack.radios[0].name = "radio";
452  ttrack.radios[0].otherradioindex = 9999;
453 
454  LsFit tfit(3);
455  tfit.update(trajectory[0].second, trajectory[0].geod);
456  tfit.update(trajectory[1].second, trajectory[1].geod);
457  for (uint16_t i=0; i<(trajectory[0].second+trajectory[1].second)/2; ++i)
458  {
459  ttrack.position.push_back(tfit);
460  }
461  for (uint16_t j=1; j<trajectory.size()-1; ++j)
462  {
463  tfit.initialize(3);
464  tfit.update(trajectory[j-1].second, trajectory[j-1].geod);
465  tfit.update(trajectory[j].second, trajectory[j].geod);
466  tfit.update(trajectory[j+1].second, trajectory[j+1].geod);
467  for (uint16_t i=static_cast<uint16_t>(.5+(trajectory[j-1].second+trajectory[j].second)/2); i<(trajectory[j].second+trajectory[j+1].second)/2; ++i)
468  {
469  ttrack.position.push_back(tfit);
470  }
471  }
472  tfit.initialize(3);
473  tfit.update(trajectory[trajectory.size()-2].second, trajectory[trajectory.size()-2].geod);
474  tfit.update(trajectory[trajectory.size()-1].second, trajectory[trajectory.size()-1].geod);
475  for (uint16_t i=static_cast<uint16_t>(.5+(trajectory[trajectory.size()-2].second+trajectory[trajectory.size()-1].second)/2); i<trajectory[trajectory.size()-1].second; ++i)
476  {
477  ttrack.position.push_back(tfit);
478  }
479 
480  for (double timestep=0.; timestep<=trajectory[trajectory.size()-1].second; timestep+=1.)
481  {
482  uint16_t timeidx = static_cast<uint16_t>(timestep);
483  gvector tpos = ttrack.position[timeidx].evalgvector(timestep);
484  gvector tvel = ttrack.position[timeidx].slopegvector(timestep);
485  printf("%f %f %f %f %f %f %f\n", timestep, tpos.lat, tpos.lon, tpos.h, tvel.lat, tvel.lon, tvel.h);
486  }
487  }
488  }
489  }
490  // Add requests
491  if ((iretn=agent->add_request("get_state",request_get_state,"", "returns current state")))
492  exit (iretn);
493  if ((iretn=agent->add_request("list_tracks",request_list_tracks,"", "returns the list of possible tracks")))
494  exit (iretn);
495  if ((iretn=agent->add_request("set_track",request_set_track,"", "sets the desired track")))
496  exit (iretn);
497  if ((iretn=agent->add_request("get_track",request_get_track,"", "returns current setting for desired track")))
498  exit (iretn);
499  if ((iretn=agent->add_request("list_radios",request_list_radios,"", "returns the list of possible radios, mine and others")))
500  exit (iretn);
501  if ((iretn=agent->add_request("match_radio",request_match_radio,"", "matches one of my radios with one of other radios")))
502  exit (iretn);
503  if ((iretn=agent->add_request("unmatch_radio",request_unmatch_radio,"", "matches one of my radios with one of other radios")))
504  exit (iretn);
505  if ((iretn=agent->add_request("list_antennas",request_list_antennas,"", "returns the list of my antennas")))
506  exit (iretn);
507  if ((iretn=agent->add_request("get_highest",request_get_highest,"", "returns the highes trackable object")))
508  exit (iretn);
509  if ((iretn=agent->add_request("debug",request_debug,"", "TUrn debugging on or off.")))
510  exit (iretn);
511 
512  // Start monitoring thread
513  thread monitor_thread(monitor);
514  ElapsedTime et;
515 
516  // Start main thread
517  agent->cinfo->agent[0].aprd = 1.;
519  while (agent->running())
520  {
521  double mjdnow = currentmjd() + .1/86400.;
522 
523  // Update all node positions, track if enabled
524  highestindex = 9999;
525  highestvalue = -DPI2;
526  for (size_t i=0; i<track.size(); ++i)
527  {
528  switch (track[i].target.type)
529  {
530  case NODE_TYPE_SATELLITE:
531  gauss_jackson_propagate(track[i].gjh, track[i].physics, track[i].target.loc, mjdnow);
532  break;
533  case NODE_TYPE_SUN:
534  jplpos(JPL_EARTH, JPL_SUN, mjdnow, &track[i].target.loc.pos.eci);
535  track[i].target.loc.pos.eci.pass++;
536  pos_eci(&track[i].target.loc);
537  break;
538  case NODE_TYPE_MOON:
539  jplpos(JPL_EARTH, JPL_MOON, mjdnow, &track[i].target.loc.pos.eci);
540  track[i].target.loc.pos.eci.pass++;
541  pos_eci(&track[i].target.loc);
542  break;
543  }
544 
545  update_target(agent->cinfo->node.loc, track[i].target);
546 
547  if (track[i].target.type == NODE_TYPE_SATELLITE)
548  {
549  if (highestindex == 9999)
550  {
551  highestindex = i;
552  highestvalue = track[i].target.elfrom;
553  }
554  else
555  {
556  if (track[i].target.elfrom > highestvalue)
557  {
558  highestindex = i;
559  highestvalue = track[i].target.elfrom;
560  }
561  }
562  }
563 
564  if (i == trackindex)
565  {
566  string output;
567  char request[100];
568  if (trackindex)
569  {
570  sprintf(request, "track_azel %f %f %f", mjdnow, DEGOF(fixangle(track[i].target.azfrom)), DEGOF((track[i].target.elfrom)));
571  if (debug)
572  {
573  printf("%f: Request: %s\n", et.lap(), request);
574  }
575 
576  // Command antennas to track
577  for (size_t j=0; j<myantennas.size(); ++j)
578  {
579  if (mjdnow - myantennas[j].beat.utc < 10.)
580  {
581  iretn = agent->send_request(myantennas[j].beat, request, output, 5.);
582  }
583  }
584 
585  // Calculate frequencies for radios
586  for (size_t j=0; j<myradios.size(); ++j)
587  {
588  if (myradios[j].otherradioindex < track[i].radios.size())
589  {
590  size_t idx = myradios[j].otherradioindex;
591  if (mjdnow - myradios[j].beat.utc < 10.)
592  {
593  track[i].radios[idx].dfreq = track[i].radios[idx].info.freq * track[i].target.close / CLIGHT;
594  myradios[j].dfreq = track[i].radios[idx].dfreq;
595  if (track[i].radios[idx].type == static_cast<uint16_t>(DeviceType::TXR))
596  {
597  myradios[j].info.freq = track[i].radios[idx].info.freq + track[i].radios[idx].dfreq;
598  }
599  else {
600  myradios[j].info.freq = track[i].radios[idx].info.freq - track[i].radios[idx].dfreq;
601  }
602  sprintf(request, "set_frequency %f", track[i].radios[idx].info.freq + track[i].radios[idx].dfreq);
603  iretn = agent->send_request(myradios[j].beat, request, output, 5.);
604  sprintf(request, "set_opmode %u", track[i].radios[idx].info.opmode);
605  iretn = agent->send_request(myradios[j].beat, request, output, 5.);
606  }
607  }
608  }
609  }
610  else if (trackinit)
611  {
612  string output;
613  string request;
614 
615  // Set radios to base frequency
616  for (size_t i=0; i<myradios.size(); ++i)
617  {
618  myradios[i].otherradioindex = 9999;
619  myradios[i].info.freq = myradios[i].basefreq;
620  myradios[i].info.opmode = myradios[i].baseopmode;
621  request = "set_frequency " + to_double(myradios[i].info.freq);
622  iretn = agent->send_request(myradios[i].beat, request, output, 5.);
623  request = "set_opmode " + to_unsigned(myradios[i].info.opmode);
624  iretn = agent->send_request(myradios[i].beat, request, output, 5.);
625  }
626 
627  // Command antennas to park
628  request = "set_azel 180. 90.";
629  for (size_t j=0; j<myantennas.size(); ++j)
630  {
631  if (mjdnow - myantennas[j].beat.utc < 10.)
632  {
633  iretn = agent->send_request(myantennas[j].beat, request, output, 5.);
634  }
635  }
636 
637  trackinit = false;
638  }
639  }
640  }
642  }
643 
644  monitor_thread.join();
645  agent->shutdown();
646 }
Radio Receiver.
Definition: jsondef.h:508
uint16_t type
Definition: agent_control.cpp:167
Definition: jsondef.h:575
Definition: agent_control.cpp:165
gj_handle gjh
Definition: agent_control.cpp:171
float area
Definition: jsondef.h:3429
int32_t finish_active_loop()
Definition: agentclass.cpp:355
int32_t request_list_radios(string &request, string &response, Agent *)
Definition: agent_control.cpp:761
FILE * get_debug_fd(double mjd=0.)
Definition: agentclass.cpp:2645
int32_t request_get_highest(string &req, string &response, Agent *)
Definition: agent_control.cpp:927
vector< LsFit > position
Definition: agent_control.cpp:172
Definition: agent_control.cpp:149
static std::vector< tlestruc > tle
Definition: agent_antenna.cpp:177
static Agent * agent
Definition: agent_control.cpp:142
3 element generic row vector
Definition: vector.h:53
int32_t json_setup_node(jsonnode json, cosmosstruc *cinfo, bool create_flag)
Setup JSON Namespace using Node description JSON.
Definition: jsonlib.cpp:6869
vector< uint16_t > rxr
Definition: jsondef.h:3914
double utc
UTC of Position.
Definition: convertdef.h:161
int i
Definition: rw_test.cpp:37
int32_t send_request(beatstruc cbeat, string request, string &output, float waitsec=5.)
Send a request over AGENT.
Definition: agentclass.cpp:424
Definition: cosmos-defs.h:101
string getNode()
Listen for heartbeat.
Definition: agentclass.cpp:2607
rvector a
2nd derivative: Alpha - acceleration
Definition: convertdef.h:483
static antstruc target
Definition: agent_antenna.cpp:160
int32_t update_target(cosmosstruc *cinfo)
Update Track list.
Definition: jsonlib.cpp:11262
int32_t request_list_tracks(string &request, string &response, Agent *)
Definition: agent_control.cpp:688
int iretn
Definition: rw_test.cpp:37
void gauss_jackson_init_eci(gj_handle &gjh, uint32_t order, int32_t mode, double dt, double utc, cartpos ipos, qatt iatt, physicsstruc &physics, locstruc &loc)
Initialize Gauss-Jackson orbit using ECI state vector.
Definition: physicslib.cpp:2479
string to_unsigned(uint64_t value, uint16_t digits, bool zerofill)
Definition: stringlib.cpp:265
int32_t wait(State state=State::RUN, double waitsec=10.)
Definition: agentclass.cpp:398
string output
Definition: agent-2-0.cpp:56
uint16_t tcv_cnt
Definition: jsondef.h:3888
uint16_t type
Definition: jsondef.h:1294
static string agentname
Definition: agent_control.cpp:140
string data_base_path(string node, string location, string agent, string filename)
Create data file path.
Definition: datalib.cpp:767
cosmosstruc * json_init()
Initialize JSON pointer map.
Definition: jsonlib.cpp:454
#define JPL_SUN
Definition: convertdef.h:120
vector< uint16_t > ant
Definition: jsondef.h:3895
const double DPI2
Double precision PI/2.
Definition: math/constants.h:18
static bool trackinit
Definition: agent_control.cpp:147
ElapsedTime et
Definition: agent_cpu_device_test.cpp:51
vector< uint16_t > txr
Definition: jsondef.h:3925
vector< string > data_list_nodes()
Get list of Nodes, directly.
Definition: datalib.cpp:583
rvector v
1st derivative: Omega - angular velocity
Definition: convertdef.h:481
#define JPL_MOON
Definition: convertdef.h:119
static string trajectoryname
Definition: agent_control.cpp:141
Definition: mathlib.h:361
vector< devicestruc > device
Vector of all general (common) information for devices (components) in node.
Definition: jsondef.h:4238
nodestruc node
Structure for summary information in node.
Definition: jsondef.h:4220
string cosmos_error_string(int32_t cosmos_errno)
Definition: cosmos-errno.cpp:45
uint16_t running()
Check if we&#39;re supposed to be running.
Definition: agentclass.cpp:391
Definition: cosmos-defs.h:90
Radio Transceiver.
Definition: jsondef.h:512
uint16_t txr_cnt
Definition: jsondef.h:3893
attstruc att
attstruc for this time.
Definition: convertdef.h:883
static vector< antennastruc > myantennas
Definition: agent_control.cpp:183
bool data_isfile(string path, off_t size)
Definition: datalib.cpp:1895
int32_t request_set_track(string &request, string &response, Agent *)
Definition: agent_control.cpp:700
string getAgent()
Definition: agentclass.cpp:2609
vector< uint16_t > tcv
Definition: jsondef.h:3920
double lap()
Lap Time.
Definition: elapsedtime.cpp:145
std::vector< cosmosstruc > nodes
Definition: agent_data-2-0.cpp:57
int32_t add_request(string token, external_request_function function, string synopsis="", string description="")
Add internal request to Agent request list with description and synopsis.
Definition: agentclass.cpp:312
void monitor()
Definition: agent_control.cpp:649
static char fname[100]
Definition: geomag.cpp:89
int32_t request_list_antennas(string &request, string &response, Agent *)
Definition: agent_control.cpp:877
Definition: agentclass.h:139
static vector< trackstruc > track
Definition: agent_control.cpp:175
qatt icrf
Definition: convertdef.h:830
string name
Definition: cubesat2obj.cpp:6
locstruc loc
Location structure.
Definition: jsondef.h:3596
#define DEGOF(rad)
Degrees of a Radian value.
Definition: math/constants.h:33
int32_t shutdown()
Shutdown agent gracefully.
Definition: agentclass.cpp:366
double fixangle(double angle)
Limit angle to range 0-2PI.
Definition: mathlib.cpp:2159
int32_t pos_eci(locstruc *loc)
Set ECI position.
Definition: convertlib.cpp:258
double h
Height in meters.
Definition: vector.h:229
vector< locstruc > gauss_jackson_propagate(gj_handle &gjh, physicsstruc &physics, locstruc &loc, double tomjd)
Definition: physicslib.cpp:2871
string name
Definition: agent_control.cpp:170
gj_handle gjh
Definition: agent_node.cpp:80
double lon
Longitude in radians.
Definition: vector.h:227
static size_t highestindex
Definition: agent_control.cpp:163
double data_ctime(string path)
Definition: datalib.cpp:1910
rvector rv_zero()
Zero row order vector.
Definition: vector.cpp:107
int32_t load_lines_multi(string fname, vector< tlestruc > &lines)
Definition: convertlib.cpp:3714
void json_destroy(cosmosstruc *cinfo)
Remove JSON pointer map.
Definition: jsonlib.cpp:491
Definition: elapsedtime.h:62
#define JPL_EARTH
Definition: convertdef.h:112
string name
Definition: agent_control.cpp:151
double currentmjd(double offset)
Current UTC in Modified Julian Days.
Definition: timelib.cpp:65
string get_nodedir(string node, bool create_flag)
Get Current Node Directory.
Definition: datalib.cpp:1572
targetstruc target
Definition: agent_control.cpp:168
posstruc pos
posstruc for this time.
Definition: convertdef.h:881
double lat
Latitude in radians.
Definition: vector.h:225
int32_t request_unmatch_radio(string &request, string &response, Agent *)
Definition: agent_control.cpp:835
vector< radiostruc > radios
Definition: agent_control.cpp:173
string utc2iso8601(double utc)
ISO 8601 version of time.
Definition: timelib.cpp:1286
backing_store_ptr info
Definition: jmemsys.h:181
float mass
Definition: jsondef.h:3425
beatstruc find_agent(string node, string agent, double waitsec=0.)
Find agent.
Definition: agentclass.cpp:559
int32_t request_match_radio(string &request, string &response, Agent *)
Definition: agent_control.cpp:778
locstruc loc
Definition: jsondef.h:1302
vector< agentstruc > agent
Single entry vector for agent information.
Definition: jsondef.h:4247
physicsstruc physics
Definition: agent_control.cpp:169
uint16_t ant_cnt
Definition: jsondef.h:3863
quaternion s
0th derivative: Quaternion
Definition: convertdef.h:479
Definition: cosmos-defs.h:100
vector< piecestruc > pieces
Vector of all pieces in node.
Definition: jsondef.h:4232
uint16_t rxr_cnt
Definition: jsondef.h:3881
int32_t request_debug(string &request, string &response, Agent *)
Definition: agent_control.cpp:936
int32_t start_active_loop()
Definition: agentclass.cpp:347
cosmosstruc * cinfo
Definition: agentclass.h:346
cartpos eci
Definition: convertdef.h:737
FILE * fp
Definition: rw_test.cpp:38
quaternion q_eye()
Identity quaternion.
Definition: vector.cpp:1310
int32_t request_get_track(string &request, string &response, Agent *)
Definition: agent_control.cpp:751
static bool debug
Definition: agent_control.cpp:185
static size_t trackindex
Definition: agent_control.cpp:162
int32_t jplpos(long from, long to, double utc, cartpos *pos)
Position from JPL Ephemeris.
Definition: ephemlib.cpp:128
devspecstruc devspec
Structure for devices (components) special data in node, by type.
Definition: jsondef.h:4241
static float highestvalue
Definition: agent_control.cpp:164
Definition: jsondef.h:4199
string mjd2iso8601(double mjd)
Definition: timelib.cpp:1316
uint16_t type
Node Type as listed in NODE_TYPE.
Definition: jsondef.h:3562
Radio Transmitter.
Definition: jsondef.h:510
3 element geodetic vector
Definition: vector.h:222
Definition: cosmos-defs.h:98
physicsstruc phys
Definition: jsondef.h:3597
static vector< radiostruc > myradios
Definition: agent_control.cpp:160
static string nodename
Definition: agent_control.cpp:139
int tle2eci(double utc, tlestruc tle, cartpos &eci)
Definition: convertlib.cpp:3466
int32_t request_get_state(string &request, string &response, Agent *)
Definition: agent_control.cpp:887
#define CLIGHT
Speed of light.
Definition: convertdef.h:49
string to_double(double value, uint16_t precision)
Definition: stringlib.cpp:285

Variable Documentation

string nodename = ""
static
string agentname = "control"
static
string trajectoryname = ""
static
Agent* agent
static
mutex cdata_mutex
static
vector<double> lastantutc
static
vector<double> lasttcvutc
static
bool trackinit = true
static
vector<radiostruc> myradios
static
size_t trackindex = 9999
static
size_t highestindex = 9999
static
float highestvalue = -DPI2
static
vector<trackstruc> track
static
vector<antennastruc> myantennas
static
bool debug
static