9 permissions_(READ_WRITE),
21 const unsigned lines_per_program)
23 output_programs.clear();
25 if (lines_per_program == 1)
31 const unsigned number_of_programs(
32 lines_per_program == 0 ? 1 : std::ceil((
double)
commands_.size() / lines_per_program));
34 if (number_of_programs > 999)
36 ROS_ERROR_STREAM(
"More than 999 programs would be generated: " << number_of_programs);
41 unsigned program_id(0);
42 unsigned line_count(0);
44 std::map<unsigned, FanucPose> poses_in_program;
46 for (
unsigned cmd_id(0); cmd_id <
commands_.size(); ++cmd_id)
52 program.append(
"/PROG ");
56 program.append(program_name);
60 program.append(
"/ATTR");
68 if (!
poses_.empty() &&
poses_.front().groups_.size() > 4)
74 std::string default_group(
"1,*,*,*,*");
79 const unsigned number_of_groups(
poses_.front().groups_.size());
82 for (
unsigned i(0); i < number_of_groups; ++i)
84 if (default_group.size() == 8)
85 default_group.append(
"1");
87 default_group.append(
"1,");
91 for (
unsigned i(0); i < 5 - number_of_groups; ++i)
93 if (default_group.size() == 8)
94 default_group.append(
"*");
96 default_group.append(
"*,");
100 program.append(
"DEFAULT_GROUP = " + default_group +
";");
101 program.append(
"\n");
106 program.append(
"/APPL\n");
108 program.append(
"\n");
112 program.append(
"/MN");
113 program.append(
"\n");
116 if (std::shared_ptr<FanucPoseCommand> pose_cmd = std::dynamic_pointer_cast<FanucPoseCommand>(
commands_.at(cmd_id)))
119 if (poses_in_program.find(pose_cmd->pose_.pose_id_) == poses_in_program.end())
122 FanucPose modified_pose(pose_cmd->pose_);
123 modified_pose.
pose_id_ = poses_in_program.size() + 1;
124 poses_in_program.insert(std::pair<unsigned, FanucPose>(pose_cmd->pose_.pose_id_, modified_pose));
128 std::string line(poses_in_program.find(pose_cmd->pose_.pose_id_)->second.getMainLineString());
130 program.append(line);
132 else if (std::shared_ptr<FanucStringCommand> str_cmd = std::dynamic_pointer_cast<FanucStringCommand>(
135 std::string line(str_cmd->cmd_);
137 program.append(line);
144 program.append(
"\n");
147 if (lines_per_program != 0 && line_count == lines_per_program - 1)
157 std::string call_line(
"CALL " + next_program_name +
" ;\n");
159 program.append(call_line);
162 program.append(
"/POS");
163 program.append(
"\n");
165 for (
auto pose_map : poses_in_program)
166 program.append(pose_map.second.getPoseLinesString());
169 program.append(
"/END\n\n");
171 output_programs.push_back(std::pair<ProgramName, Program>(program_name, program));
175 poses_in_program.clear();
181 program.append(
"/POS");
182 program.append(
"\n");
184 for (
auto pose_map : poses_in_program)
185 program.append(pose_map.second.getPoseLinesString());
188 program.append(
"/END\n\n");
189 output_programs.push_back(std::pair<ProgramName, Program>(program_name, program));
190 return output_programs.size();
206 const std::string ip_address,
207 const std::string port_number,
208 const std::string username,
209 const std::string password)
212 for (
auto &program : programs)
214 std::ofstream ls_program;
215 ls_program.open(
"/tmp/" + program.first +
".ls");
216 if (!ls_program.is_open())
217 throw std::runtime_error(
"Could not open /tmp/" + program.first +
".ls for writing");
219 ls_program << program.second;
223 ROS_INFO_STREAM(
"Trying to upload " + program.first +
".ls at " + ip_address);
227 curlite.
set(CURLOPT_URL,
"ftp://@" + ip_address +
":" + port_number +
"/\\" + program.first +
".ls");
228 curlite.
set(CURLOPT_USERNAME, username);
229 curlite.
set(CURLOPT_PASSWORD, password);
230 curlite.
set(CURLOPT_UPLOAD,
true);
233 std::ifstream ifs(
"/tmp/" + program.first +
".ls", std::ios::binary);
236 double total_secs = curlite.
getInfo<
double>(CURLINFO_TOTAL_TIME);
239 catch (std::exception &e)
241 throw std::runtime_error(e.what());
249 throw std::runtime_error(
"Program name cannot be empty");
250 if (name.find(
' ') != std::string::npos)
251 throw std::runtime_error(
"Program name cannot contain a space");
277 throw std::runtime_error(
"Pose is not valid");
280 throw std::runtime_error(
"Pose does not have the same groups/axes of the first pose in the program");
288 std::shared_ptr<FanucPoseCommand> cmd = std::make_shared<FanucPoseCommand>(pose);
296 throw std::runtime_error(
"Invalid pose id (0)");
298 for (
auto pose_tmp :
poses_)
300 if (pose_tmp.pose_id_ == pose.
pose_id_)
303 std::shared_ptr<FanucPoseCommand> cmd = std::make_shared<FanucPoseCommand>(pose);
304 cmd->pose_.groups_ = pose_tmp.groups_;
306 if (!cmd->pose_.isValid())
307 throw std::runtime_error(
"Pose is not valid");
314 throw std::runtime_error(
"Pose ID " + std::to_string(pose.
pose_id_) +
" was not found");
319 std::shared_ptr<FanucStringCommand> cmd = std::make_shared<FanucStringCommand>(
"!" + comment +
";");
325 std::shared_ptr<FanucStringCommand> cmd = std::make_shared<FanucStringCommand>(
";");
332 const std::string DO_id(std::to_string(digital_out_id));
333 const std::string on_off(state ==
true ?
"ON" :
"OFF");
334 std::shared_ptr<FanucStringCommand> cmd = std::make_shared<FanucStringCommand>(
"DO[" + DO_id +
"]=" + on_off +
";");
339 const double pulse_time)
342 throw std::runtime_error(
"Pulse time must be > 0");
344 const std::string digital_output_id(std::to_string(digital_out_id));
345 std::ostringstream ss;
346 ss.imbue(std::locale(
"C"));
347 ss << std::fixed << std::setprecision(2);
349 const std::string time = ss.str();
350 std::shared_ptr<FanucStringCommand> cmd = std::make_shared<FanucStringCommand>(
351 "DO[" + digital_output_id +
"]=PULSE," + time +
"sec;");
358 throw std::runtime_error(
"Time must be >= 0");
360 std::ostringstream ss;
361 ss.imbue(std::locale(
"C"));
362 ss << std::fixed << std::setprecision(2);
364 const std::string duration = ss.str();
365 std::shared_ptr<FanucStringCommand> cmd = std::make_shared<FanucStringCommand>(
"WAIT " + duration +
"(sec);");
372 const std::string DI_id(std::to_string(digital_in_id));
373 const std::string DI_state(state ?
"ON" :
"OFF");
374 std::shared_ptr<FanucStringCommand> cmd = std::make_shared<FanucStringCommand>(
375 "WAIT DI[" + DI_id +
"]=" + DI_state +
";");
382 throw std::runtime_error(
"UFrame number exceeds maximum of 9, UFrame ID given = " + std::to_string(uf_id));
384 const std::string uframe(std::to_string(uf_id));
385 std::shared_ptr<FanucStringCommand> cmd = std::make_shared<FanucStringCommand>(
"UFRAME_NUM=" + uframe +
";");
391 if (ut_id == 0 || ut_id > 9)
392 throw std::runtime_error(
"UTool ID must be between 1 and 9. UTool ID given = " + std::to_string(ut_id));
394 const std::string utool(std::to_string(ut_id));
395 std::shared_ptr<FanucStringCommand> cmd = std::make_shared<FanucStringCommand>(
"UTOOL_NUM=" + utool +
";");
400 const unsigned value)
402 const std::string group_id(std::to_string(
id));
403 const std::string group_value(std::to_string(value));
404 std::shared_ptr<FanucStringCommand> cmd = std::make_shared<FanucStringCommand>(
405 "GO[" + group_id +
"]=" + group_value +
";");
413 throw std::runtime_error(
"Register ID starts at 1. 0 Given register ID = 0");
415 const std::string id(std::to_string(r_id));
416 std::ostringstream ss;
417 ss.imbue(std::locale(
"C"));
418 ss << std::fixed << std::setprecision(2);
420 const std::string r_value = ss.str();
421 std::shared_ptr<FanucStringCommand> cmd = std::make_shared<FanucStringCommand>(
"R[" +
id +
"]=" + r_value +
";");
427 std::string name(program_name);
428 std::transform(name.begin(), name.end(), name.begin(), ::toupper);
429 std::shared_ptr<FanucStringCommand> cmd = std::make_shared<FanucStringCommand>(
"CALL " + name +
";");
435 std::string name(program_name);
436 std::transform(name.begin(), name.end(), name.begin(), ::toupper);
437 std::shared_ptr<FanucStringCommand> cmd = std::make_shared<FanucStringCommand>(
"RUN " + name +
";");
444 for (std::vector<unsigned>::iterator iter(
labels_id_.begin()); iter !=
labels_id_.end(); ++iter)
446 throw std::runtime_error(
"Label ID does not exist. Given label ID = " + std::to_string(
id));
449 const std::string lbl_id(std::to_string(
id));
450 std::shared_ptr<FanucStringCommand> cmd = std::make_shared<FanucStringCommand>(
"LBL[" + lbl_id +
"];");
457 const std::string lbl_id(std::to_string(
id));
458 std::shared_ptr<FanucStringCommand> cmd = std::make_shared<FanucStringCommand>(
"JMP LBL[" + lbl_id +
"];");
464 const std::string datamon_id(std::to_string(
id));
465 std::shared_ptr<FanucStringCommand> cmd = std::make_shared<FanucStringCommand>(
"Sample Start[" + datamon_id +
"];");
471 std::shared_ptr<FanucStringCommand> cmd = std::make_shared<FanucStringCommand>(
"Sample End;");
476 const std::string start,
477 const std::string stop)
479 std::shared_ptr<FanucStringCommand> cmd = std::make_shared<FanucStringCommand>(
480 "FOR R[" + std::to_string(reg_id) +
"]=" + start +
" TO " + stop +
";");
486 const unsigned start,
489 std::shared_ptr<FanucStringCommand> cmd = std::make_shared<FanucStringCommand>(
490 "FOR R[" + std::to_string(reg_id) +
"]=" + std::to_string(start)
491 +
" TO " + std::to_string(stop) +
";");
498 throw std::runtime_error(
"Cannot append ENDFOR without appending a FOR first.");
501 std::shared_ptr<FanucStringCommand> cmd = std::make_shared<FanucStringCommand>(
"ENDFOR;");
507 std::shared_ptr<FanucStringCommand> cmd = std::make_shared<FanucStringCommand>(command +
";");
515 for (
auto pose_tmp :
poses_)
517 if (pose_tmp.pose_id_ == pose_id)
529 const unsigned number)
538 throw std::runtime_error(
"Line number exceeds 99999! Line number = " + std::to_string(number));
540 std::string line_header(std::to_string(number));
541 line_header.append(
":");
543 int characters_to_be_added(6 - line_header.size());
544 if (characters_to_be_added < 0)
545 throw std::runtime_error(
"Error computing line number characters");
547 for (
unsigned i(0); i < (unsigned)characters_to_be_added; ++i)
548 line_header.insert(0,
" ");
550 line.insert(0, line_header);
554 const unsigned number)
556 std::string twk_name(name);
557 unsigned digit_count(std::to_string(number).size());
566 twk_name.erase(twk_name.size() + offset, -offset);
567 twk_name.append(std::to_string(number));
void appendGroupOutput(const unsigned id, const unsigned value)
void appendCall(const std::string program_name)
void appendComment(const std::string comment)
void setPermissions(const FanucPostProcessor::Permissions perms)
FanucPostProcessor()
Default Constructor.
void appendCustomCommand(const std::string command)
void appendSetRegister(const unsigned r_id, const double value)
void prependLineNumber(std::string &line, const unsigned number)
std::string program_name_
unsigned generatePrograms(std::vector< std::pair< ProgramName, Program >> &output_programs, const unsigned lines_per_program=0)
void appendPose(FanucPose &pose)
std::string program_comment_
void appendPoseId(FanucPose &pose)
void appendJumpLabel(const unsigned id)
void appendLabel(const unsigned id)
std::vector< FanucGroup > groups_
void appendDigitalOutput(const unsigned digital_out_id, const bool state)
bool tweakProgramName(ProgramName &name, const unsigned number)
std::vector< unsigned > labels_id_
void setProgramName(std::string name)
ValueType getInfo(CURLINFO key, ValueType const &defaultValue=ValueType())
void useLineNumbers(bool line_numbers)
const unsigned program_name_max_size_
std::vector< FanucPose > poses_
bool getPoseFromId(const unsigned pose_id, FanucPose &pose)
std::vector< std::shared_ptr< FanucCommand > > commands_
void appendDataMonitorStart(const unsigned id)
void setProgramComment(const std::string comment)
bool set(CURLoption opt, ValueType value)
#define ROS_INFO_STREAM(args)
bool hasSameGroupsAxes(const FanucPose &other) const
void setApplicative(const std::string appl)
void appendWait(const double time)
void appendUFrame(const unsigned uf_id)
void uploadToFtp(const std::vector< std::pair< ProgramName, Program >> programs, const std::string ip_address, const std::string port_number="21", const std::string username="", const std::string password="")
#define ROS_ERROR_STREAM(args)
void appendUTool(const unsigned ut_id)
std::string permissionsToString(Permissions perm)
void appendFor(const unsigned reg_id, const std::string start, const std::string stop)
void appendRun(const std::string program_name)
FanucPostProcessor::Permissions permissions_
void appendDataMonitorStop()