📄 nml_mod.cc
字号:
// check channel for validity if (errorLog == NULL) return -1; // write args to NML message va_start (ap, fmt); vsprintf (text_msg.text, fmt, ap); va_end (ap); // rcs_print("%s\n", text_msg.text); // force a NULL at the end for safety text_msg.text[NML_TEXT_LEN - 1] = 0; // write it if (errorLog->write (text_msg) < 0) { return -1; } return 0;}intNML_MODULE::requestDisplay (const char *display){ NML_DISPLAY display_msg; // check channel for validity if (errorLog == NULL) return -1; if (!errorLog->valid ()) return -1; // write args to NML message strcpy (display_msg.display, display); // force a NULL at the end for safety display_msg.display[NML_DISPLAY_LEN - 1] = 0; // write it errorLog->write (display_msg); return 0;}// The rest of the functions here were taken from RCS_MODULE_C// Virtual Functions//voidNML_MODULE::DECISION_PROCESS (void){}voidNML_MODULE::setSelfCommand (RCS_CMD_MSG * cmd){ if (NULL == cmd || NULL == statusOutData || NULL == commandInData || NULL == commandIn) { return; } if (NULL == commandIn->cms) { return; } if (cmd->size > commandIn->cms->size) { rcs_print_error ("NML_MODULE::setSelfCommand, Command too big! %d(0x%X) > %d(0x%X)\n", cmd->size, cmd->size, commandIn->cms->size, commandIn->cms->size); } statusOutData->echo_serial_number++; cmd->serial_number = statusOutData->echo_serial_number + 1; commandIn->write (cmd); memcpy (commandInData, cmd, cmd->size); statusOutData->command_type = cmd->type; force_command = 1;}voidNML_MODULE::read_command_in (){ NMLTYPE type; if (force_command) { force_command = 0; return; } switch (type = commandIn->read ()) { case -1: logError ("Can not read input command. (%d)", commandIn->error_type); if (NULL != statusOutData) { statusOutData->command_type = type; } break; case 0: // no new command break; default: commandInData = commandIn->get_address (); if (NULL != statusOutData) { statusOutData->command_type = type; } break; }}voidNML_MODULE::read_subordinates_status (){ int t; NMLTYPE type; // read NML STATUS buffer from subordinates for (t = 0; t < numSubordinates; t++) { if (NULL == subs[t]) { continue; } if (NULL == subs[t]->statusIn) { continue; } switch (type = subs[t]->statusIn->peek ()) { case -1: // error on NML channel logError ("Can not read status from subodinate %s (%d).\n", subs[t]->statusIn->cms->BufferName, subs[t]->statusIn->error_type); break; case 0: // no new data break; default: subs[t]->statusInData = subs[t]->statusIn->get_address (); if (NULL != subs[t]->statusInData && NULL != subs[t]->commandOutData) { if (subs[t]->statusInData->echo_serial_number != subs[t]->commandOutData->serial_number) { subs[t]->statusInData->status = RCS_EXEC; } } // something new in STATUS break; } }}voidNML_MODULE::READ_COMM_BUFFERS (void){ read_command_in (); read_subordinates_status (); check_if_new_command ();}voidNML_MODULE::PRE_PROCESS (void){}voidNML_MODULE::POST_PROCESS (void){}voidNML_MODULE::write_status_out (){ if (NULL == statusOutData) { return; } // update NML STATUS statusOutData->command_type = commandInData->type; statusOutData->state = state; statusOutData->status = (RCS_STATUS) status; if (status == RCS_DONE && last_command_completed_serial_number != commandInData->serial_number) { last_command_completed_serial_number = commandInData->serial_number; commands_executed++; } statusOutData->source_line = source_line; if (NULL != source_file) { strncpy (statusOutData->source_file, source_file, 64); } // write STATUS if (-1 == statusOut->write (statusOutData)) { logError ("bad write to status (%d)\n", statusOut->error_type); }}voidNML_MODULE::write_commands_to_subordinates (){ int t; // write subordinates for (t = 0; t < numSubordinates; t++) { if (subs[t]->commandOutData == NULL) { continue; } if (subs[t]->commandOutData->type == 0) { continue; } if (subs[t]->statusInData != NULL) { if (subs[t]->statusInData->echo_serial_number == subs[t]->commandOutData->serial_number && subs[t]->statusInData->echo_serial_number > 0 && subs[t]->modification_number <= 0) { subs[t]->commandOutData->type = 0; continue; } } if (-1 == subs[t]->commandOut->write (subs[t]->commandOutData)) { logError ("Error writing to %s (%d).\n", subs[t]->commandOut->cms->BufferName, subs[t]->commandOut->error_type); } else { //if the subordinates command buffer is queued then // mark the command so it isn't sent out again. if (subs[t]->commandOut->cms->queuing_enabled) { subs[t]->commandOutData->type = 0; } } }}voidNML_MODULE::WRITE_COMM_BUFFERS (void){ write_status_out (); write_commands_to_subordinates ();}//***********************************************************************************//* Overhead ** Overhead ** Overhead ** Overhead **Overhead ** Overhead **Overhead **//***********************************************************************************voidNML_MODULE::controller (void){ check_cycle_time_start (); READ_COMM_BUFFERS (); PRE_PROCESS (); /* reset state table flags */ stateBegin = 1; matched = 0; if (commandInData != NULL) { if (statusOutData != NULL) { if (statusOutData->command_type > 0) { DECISION_PROCESS (); } } } POST_PROCESS (); WRITE_COMM_BUFFERS (); check_cycle_time_end ();}voidNML_MODULE::check_cycle_time_start (){ start_run_time = etime (); cycles++; if (cycles < 2) { start_cycle_time = start_run_time; } else { last_cycle_time = start_run_time - last_start_run_time; if (last_cycle_time > max_cycle_time) { max_cycle_time = last_cycle_time; } if (last_cycle_time < min_cycle_time) { min_cycle_time = last_cycle_time; } } last_start_run_time = start_run_time;}voidNML_MODULE::check_if_new_command (void){ if (NULL == commandInData) { return; } if (NULL == statusOutData) { return; } if (statusOutData->echo_serial_number != commandInData->serial_number) { state = NEW_COMMAND; status = RCS_EXEC; commands_received++; statusOutData->echo_serial_number = commandInData->serial_number; statusOutData->command_type = commandInData->type; command_time_averaged = 0; new_command_sequence = 1; new_line_num_sequence = 1;// exec_status.line_num = 0; }}voidNML_MODULE::print_statistics (){ double total_time = stop_run_time - start_cycle_time; rcs_print ("\n*************************************************\n"); if (NULL != proc_name) { rcs_print ("Module Name: %s\n", proc_name); } rcs_print ("Total cycles: %d\n", cycles); rcs_print ("Total time: %f\n", total_time); if (cycles > 0) { rcs_print ("Average Cycle Time: %f\n", total_time / cycles); } else { rcs_print ("Average Cycle Time: CAN NOT BE DETERMINED\n"); } rcs_print ("Minimum Cycle Time: %f\n", min_cycle_time); rcs_print ("Max Cycle Time: %f\n", max_cycle_time); rcs_print ("Commands Received: %d\n", commands_received); if (total_time > 0) { rcs_print ("Commands Received per second: %f\n", commands_received / total_time); } else { rcs_print ("Commands Received per second: CAN NOT BE DETERMINED\n"); } if (total_time > 0) { rcs_print ("Load: %f%%\n", total_run_time * 100 / total_time); } else { rcs_print ("Load: CAN NOT BE DETERMINED\n"); } rcs_print ("*************************************************\n");}voidNML_MODULE::check_cycle_time_end (){ stop_run_time = etime (); total_run_time += stop_run_time - start_run_time;}voidNML_MODULE::set_file_and_line (char *_source_file, int _source_line){ temp_file = _source_file; temp_line = _source_line;}/* 'stateBegin' and 'matched' are set to 1 and 0, respectively, by controller(). Calls to stateMatch() in the controller logic will use these to determine if the line number needs to be set to 1 or incremented, and if matches have occurred so that only one state table line is executed per pass. */intNML_MODULE::stateMatch (char *_source_file, int _source_line, int st, int conds){ set_file_and_line (_source_file, _source_line); return stateMatch (st, conds);}intNML_MODULE::stateMatch (int st, int conds){ if (matched) { return 0; } // check if this is the first line in the state table if (stateBegin) { if (NULL != statusOutData) { statusOutData->line = 0; } source_line = -1; source_file = NULL; stateBegin = 0; if (state != st || !conds) { temp_line = -1; temp_file = NULL; } } else { // lines have gone before-- just increment if (NULL != statusOutData) { statusOutData->line++; } } // see if we match state and conditions if (state == st && conds) { matched = 1; source_file = temp_file; source_line = temp_line; return 1; } else { // no match return 0; }}voidNML_MODULE::stateNext (int st){ state = (RCS_STATE) st;}voidNML_MODULE::stateNext (RCS_STATE st){ state = (RCS_STATE) st;}intNML_MODULE::sendCommand (RCS_CMD_MSG * cmd_msg, int sub_num){ if (sub_num >= numSubordinates || sub_num < 0) { return -1; } if (cmd_msg == NULL) { return -1; } if (cmd_msg->size <= 0 || cmd_msg->type <= 0) { return -1; } if (NULL == subs[sub_num]) { return -1; } if (NULL == subs[sub_num]->statusInData) { return -1; } if (NULL == subs[sub_num]->commandOutData) { return -1; } if (NULL == subs[sub_num]->commandOut) { return -1; } if (NULL == subs[sub_num]->commandOut->cms) { return -1; } if (cmd_msg->size >= subs[sub_num]->commandOut->cms->size) { return -1; } memcpy (subs[sub_num]->commandOutData, cmd_msg, cmd_msg->size); subs[sub_num]->modification_number = 0; subs[sub_num]->commandOutData->serial_number = subs[sub_num]->statusInData->echo_serial_number + 1; return (0);}intNML_MODULE::modifyCommand (RCS_CMD_MSG * cmd_msg, int sub_num){ if (sub_num >= numSubordinates || sub_num < 0) { return -1; } if (cmd_msg == NULL) { return -1; } if (NULL == subs[sub_num]) { return -1; } if (NULL == subs[sub_num]->commandOutData) { return -1; } cmd_msg->serial_number = subs[sub_num]->commandOutData->serial_number; memcpy (subs[sub_num]->commandOutData, cmd_msg, cmd_msg->size); subs[sub_num]->modification_number++; return (0);}voidNML_MODULE::loadDclock (double expiration){ Dclock_expiration = expiration; Dclock_start_time = etime ();}intNML_MODULE::checkDclock (){ return (fabs (etime () - Dclock_start_time) < Dclock_expiration);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -