NEW: support software limit of axis control

Change-Id: I0d241aeddeed112b21ed576ce793c3e9f061c923
Signed-off-by: Stone Li <stone.li@bambulab.com>
This commit is contained in:
Stone Li 2022-08-31 16:32:56 +08:00 committed by Lane.Wei
parent 8e1fd89430
commit 2dc2d8252d
8 changed files with 315 additions and 7 deletions

View file

@ -340,6 +340,8 @@ set(SLIC3R_GUI_SOURCES
GUI/DesktopIntegrationDialog.hpp
GUI/PublishDialog.cpp
GUI/PublishDialog.hpp
GUI/RecenterDialog.cpp
GUI/RecenterDialog.hpp
GUI/BindDialog.cpp
GUI/BindDialog.hpp
GUI/SelectMachine.hpp

View file

@ -356,6 +356,7 @@ MachineObject::MachineObject(NetworkAgent* agent, std::string name, std::string
mc_print_percent = 0;
mc_print_sub_stage = 0;
mc_left_time = 0;
home_flag = -1;
printing_speed_lvl = PrintingSpeedLevel::SPEED_LEVEL_INVALID;
}
@ -1026,6 +1027,22 @@ bool MachineObject::is_system_printing()
return false;
}
bool MachineObject::is_axis_at_home(std::string axis)
{
if (home_flag < 0)
return true;
if (axis == "X") {
return home_flag & 1 == 1;
} else if (axis == "Y") {
return home_flag >> 1 & 1 == 1;
} else if (axis == "Z") {
return home_flag >> 2 & 1 == 1;
} else {
return true;
}
}
wxString MachineObject::get_curr_stage()
{
if (stage_list_info.empty()) {
@ -1399,11 +1416,11 @@ int MachineObject::command_set_printing_speed(PrintingSpeedLevel lvl)
int MachineObject::command_axis_control(std::string axis, double unit, double value, int speed)
{
char cmd[64];
char cmd[256];
if (axis.compare("X") == 0
|| axis.compare("Y") == 0
|| axis.compare("Z") == 0) {
sprintf(cmd, "G91 \nG0 %s%0.1f F%d\n", axis.c_str(), value * unit, speed);
sprintf(cmd, "M211 S \nM211 X1 Y1 Z1\nM1002 push_ref_mode\nG91 \nG1 %s%0.1f F%d\nM1002 pop_ref_mode\nM211 R\n", axis.c_str(), value * unit, speed);
}
else if (axis.compare("E") == 0) {
sprintf(cmd, "M83 \nG0 %s%0.1f F%d\n", axis.c_str(), value * unit, speed);
@ -1799,6 +1816,10 @@ int MachineObject::parse_json(std::string payload)
print_type = jj["print_type"].get<std::string>();
}
if (jj.contains("home_flag")) {
home_flag = jj["home_flag"].get<int>();
}
if (jj.contains("mc_remaining_time")) {
if (jj["mc_remaining_time"].is_string())
mc_left_time = stoi(j["print"]["mc_remaining_time"].get<std::string>()) * 60;

View file

@ -459,6 +459,7 @@ public:
int mc_print_percent; /* left print progess in percent */
int mc_left_time; /* left time in seconds */
int last_mc_print_stage;
int home_flag;
bool is_system_printing();
int print_error;
@ -467,6 +468,8 @@ public:
int m_push_count = 0;
bool calibration_done { false };
bool is_axis_at_home(std::string axis);
wxString get_curr_stage();
// return curr stage index of stage list
int get_curr_stage_idx();

View file

@ -0,0 +1,183 @@
#include "RecenterDialog.hpp"
#include <slic3r/GUI/I18N.hpp>
#include <wx/dcgraph.h>
#include <wx/dcmemory.h>
#include <slic3r/GUI/Widgets/Label.hpp>
#define BORDER FromDIP(25)
#define DRAW_PANEL_SIZE wxSize(FromDIP(475), FromDIP(100))
wxString hint1 = _L("Please perform \"recenter ");
wxString hint2 = _L("\" action to locate the current position of the extruder to prevent device breakdown by moving the axis out of line.");
namespace Slic3r { namespace GUI {
RecenterDialog::RecenterDialog(wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style)
: DPIDialog(parent, id, _L("Reminder"), pos, size, style)
{
std::string icon_path = (boost::format("%1%/images/BambuStudioTitle.ico") % resources_dir()).str();
SetIcon(wxIcon(encode_path(icon_path.c_str()), wxBITMAP_TYPE_ICO));
init_bitmap();
auto* main_sizer = new wxBoxSizer(wxVERTICAL);
auto* button_sizer = new wxBoxSizer(wxHORIZONTAL);
wxPanel* m_line_top = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxSize(-1, 1), wxTAB_TRAVERSAL);
m_line_top->SetBackgroundColour(wxColour(166, 169, 170));
m_button_confirm = new Button(this, _L("Center"));
m_button_confirm->SetFont(Label::Body_12);
m_button_confirm->SetMinSize(wxSize(-1, FromDIP(24)));
m_button_confirm->SetCornerRadius(FromDIP(12));
StateColor confirm_btn_bg(std::pair<wxColour, int>(wxColour(61, 203, 115), StateColor::Hovered),
std::pair<wxColour, int>(wxColour(0, 174, 66), StateColor::Normal));
m_button_confirm->SetBackgroundColor(confirm_btn_bg);
m_button_confirm->SetBorderColor(wxColour(0, 174, 66));
m_button_confirm->SetTextColor(*wxWHITE);
m_button_close = new Button(this, _L("Close"));
m_button_close->SetFont(Label::Body_12);
m_button_close->SetMinSize(wxSize(-1, FromDIP(24)));
m_button_close->SetCornerRadius(FromDIP(12));
StateColor close_btn_bg(std::pair<wxColour, int>(wxColour(206, 206, 206), StateColor::Hovered),
std::pair<wxColour, int>(*wxWHITE, StateColor::Normal));
m_button_close->SetBackgroundColor(close_btn_bg);
m_button_close->SetBorderColor(wxColour(38, 46, 48));
m_button_close->SetTextColor(wxColour(38, 46, 48));
button_sizer->AddStretchSpacer();
button_sizer->Add(m_button_confirm);
button_sizer->AddSpacer(FromDIP(20));
button_sizer->Add(m_button_close);
main_sizer->Add(m_line_top, 0, wxEXPAND, 0);
main_sizer->AddSpacer(DRAW_PANEL_SIZE.y);
main_sizer->Add(button_sizer, 0, wxBOTTOM | wxRIGHT | wxEXPAND, BORDER);
SetSizer(main_sizer);
CenterOnParent();
this->SetSize(wxSize(DRAW_PANEL_SIZE.x, -1));
this->SetMinSize(wxSize(DRAW_PANEL_SIZE.x, -1));
Fit();
this->Bind(wxEVT_PAINT, &RecenterDialog::OnPaint, this);
m_button_confirm->Bind(wxEVT_BUTTON, &RecenterDialog::on_button_confirm, this);
m_button_close->Bind(wxEVT_BUTTON, &RecenterDialog::on_button_close, this);
}
RecenterDialog::~RecenterDialog() {}
void RecenterDialog::init_bitmap() {
m_home_bmp = ScalableBitmap(this, "monitor_axis_home_icon", 30);
}
void RecenterDialog::OnPaint(wxPaintEvent& event){
wxPaintDC dc(this);
wxGCDC dc2(dc);
render(dc2);
}
void RecenterDialog::render(wxDC& dc) {
wxSize size = GetSize();
dc.SetFont(Label::Body_14);
dc.SetTextForeground(*wxBLACK);
wxPoint pos_start = wxPoint(BORDER, BORDER);
wxSize hint1_size = dc.GetTextExtent(hint1);
wxPoint pos_hint1 = pos_start;
pos_hint1.y += (m_home_bmp.GetBmpWidth() - hint1_size.y) / 2;
dc.DrawText(hint1, pos_hint1);
wxPoint pos_bmp = pos_start;
pos_bmp.x += hint1_size.x;
dc.DrawBitmap(m_home_bmp.bmp(), pos_bmp);
wxSize hint2_size = dc.GetTextExtent(hint2);
wxPoint pos_hint2 = pos_hint1;
pos_hint2.x = pos_hint2.x + hint1_size.x + m_home_bmp.GetBmpWidth();
if (hint2_size.x + pos_hint2.x + BORDER > DRAW_PANEL_SIZE.x) {
bool is_ch = false;
if (hint2[0] > 0x80 && hint2[1] > 0x80)
is_ch = true;
wxString fisrt_line;
wxString remaining_line;
wxString count_txt;
int new_line_pos = 0;
for (int i = 0; i < hint2.length(); i++) {
count_txt += hint2[i];
auto text_size = dc.GetTextExtent(count_txt);
if (text_size.x + pos_hint2.x + BORDER < DRAW_PANEL_SIZE.x)
{
if (hint2[i] == ' ' || hint2[i] == '\n')
new_line_pos = i;
}
else {
if (!is_ch) {
fisrt_line = hint2.SubString(0, new_line_pos);
remaining_line = hint2.SubString(new_line_pos + 1, hint2.length());
break;
}
else {
fisrt_line = hint2.SubString(0, i);
remaining_line = hint2.SubString(i, hint2.length());
break;
}
count_txt = "";
}
}
dc.DrawText(fisrt_line, pos_hint2);
count_txt = "";
new_line_pos = 0;
for (int i = 0; i < remaining_line.length(); i++) {
count_txt += remaining_line[i];
auto text_size = dc.GetTextExtent(count_txt);
if (text_size.x + BORDER + BORDER < DRAW_PANEL_SIZE.x)
{
if (remaining_line[i] == ' ' || remaining_line[i] == '\n')
new_line_pos = i;
}
else {
if (!is_ch){
remaining_line[new_line_pos] = '\n';
}
else {
remaining_line.insert(i, '\n');
}
count_txt = "";
}
}
wxPoint pos_txt = pos_hint1;
pos_txt.y += dc.GetCharHeight();
dc.DrawText(remaining_line, pos_txt);
}
else
dc.DrawText(hint2, pos_hint2);
}
void RecenterDialog::on_button_confirm(wxCommandEvent& event) {
if (this->IsModal())
this->EndModal(wxID_OK);
else
this->Close();
}
void RecenterDialog::on_button_close(wxCommandEvent& event) {
this->Close();
}
void RecenterDialog::on_dpi_changed(const wxRect& suggested_rect) {
init_bitmap();
m_button_confirm->SetMinSize(wxSize(-1, FromDIP(24)));
m_button_confirm->SetCornerRadius(FromDIP(12));
m_button_close->SetMinSize(wxSize(-1, FromDIP(24)));
m_button_close->SetCornerRadius(FromDIP(12));
}
}} // namespace Slic3r::GUI

View file

@ -0,0 +1,38 @@
#ifndef slic3r_GUI_RecenterDialog_hpp_
#define slic3r_GUI_RecenterDialog_hpp_
#include "GUI_Utils.hpp"
#include <wx/statbmp.h>
#include "Widgets/Button.hpp"
#include <wx/stattext.h>
namespace Slic3r { namespace GUI {
class RecenterDialog : public DPIDialog
{
private:
wxStaticText* m_staticText_hint;
Button* m_button_confirm;
Button* m_button_close;
wxStaticBitmap* m_bitmap_home;
ScalableBitmap m_home_bmp;
void init_bitmap();
void OnPaint(wxPaintEvent& event);
void render(wxDC& dc);
void on_button_confirm(wxCommandEvent& event);
void on_button_close(wxCommandEvent& event);
void on_dpi_changed(const wxRect& suggested_rect) override;
public:
RecenterDialog(wxWindow* parent,
wxWindowID id = wxID_ANY,
const wxString& title = wxEmptyString,
const wxPoint& pos = wxDefaultPosition,
const wxSize& size = wxDefaultSize,
long style = wxCLOSE_BOX | wxCAPTION);
~RecenterDialog();
};
}} // namespace Slic3r::GUI
#endif

View file

@ -9,7 +9,7 @@
#include "slic3r/Utils/Http.hpp"
#include "libslic3r/Thread.hpp"
#include "RecenterDialog.hpp"
namespace Slic3r { namespace GUI {
@ -1355,6 +1355,12 @@ void StatusPanel::update(MachineObject *obj)
m_machine_ctrl_panel->Thaw();
}
void StatusPanel::show_recenter_dialog() {
RecenterDialog dlg(this);
if (dlg.ShowModal() == wxID_OK)
obj->command_go_home();
}
void StatusPanel::show_error_message(wxString msg)
{
m_error_text->SetLabel(msg);
@ -1944,6 +1950,27 @@ void StatusPanel::reset_printing_values()
void StatusPanel::on_axis_ctrl_xy(wxCommandEvent &event)
{
if (!obj) return;
//check is at home
if (event.GetInt() == 1
|| event.GetInt() == 3
|| event.GetInt() == 5
|| event.GetInt() == 7) {
if (!obj->is_axis_at_home("X")) {
BOOST_LOG_TRIVIAL(info) << "axis x is not at home";
show_recenter_dialog();
return;
}
} else if (event.GetInt() == 0
|| event.GetInt() == 2
|| event.GetInt() == 4
|| event.GetInt() == 6) {
if (!obj->is_axis_at_home("Y")) {
BOOST_LOG_TRIVIAL(info) << "axis y is not at home";
show_recenter_dialog();
return;
}
}
if (event.GetInt() == 0) { obj->command_axis_control("Y", 1.0, 10.0f, 3000); }
if (event.GetInt() == 1) { obj->command_axis_control("X", 1.0, -10.0f, 3000); }
if (event.GetInt() == 2) { obj->command_axis_control("Y", 1.0, -10.0f, 3000); }
@ -1955,24 +1982,53 @@ void StatusPanel::on_axis_ctrl_xy(wxCommandEvent &event)
if (event.GetInt() == 8) { obj->command_go_home(); }
}
bool StatusPanel::check_axis_z_at_home(MachineObject* obj)
{
if (obj) {
if (!obj->is_axis_at_home("Z")) {
BOOST_LOG_TRIVIAL(info) << "axis z is not at home";
show_recenter_dialog();
return false;
}
return true;
}
return false;
}
void StatusPanel::on_axis_ctrl_z_up_10(wxCommandEvent &event)
{
if (obj) obj->command_axis_control("Z", 1.0, -10.0f, 900);
if (obj) {
if (!check_axis_z_at_home(obj))
return;
obj->command_axis_control("Z", 1.0, -10.0f, 900);
}
}
void StatusPanel::on_axis_ctrl_z_up_1(wxCommandEvent &event)
{
if (obj) obj->command_axis_control("Z", 1.0, -1.0f, 900);
if (obj) {
if (!check_axis_z_at_home(obj))
return;
obj->command_axis_control("Z", 1.0, -1.0f, 900);
}
}
void StatusPanel::on_axis_ctrl_z_down_1(wxCommandEvent &event)
{
if (obj) obj->command_axis_control("Z", 1.0, 1.0f, 900);
if (obj) {
if (!check_axis_z_at_home(obj))
return;
obj->command_axis_control("Z", 1.0, 1.0f, 900);
}
}
void StatusPanel::on_axis_ctrl_z_down_10(wxCommandEvent &event)
{
if (obj) obj->command_axis_control("Z", 1.0, 10.0f, 900);
if (obj) {
if (!check_axis_z_at_home(obj))
return;
obj->command_axis_control("Z", 1.0, 10.0f, 900);
}
}
void StatusPanel::on_axis_ctrl_e_up_10(wxCommandEvent &event)

View file

@ -277,8 +277,10 @@ protected:
void on_subtask_clean(wxCommandEvent &event);
void show_error_message(wxString msg);
void error_info_reset();
void show_recenter_dialog();
/* axis control */
bool check_axis_z_at_home(MachineObject* obj);
void on_axis_ctrl_xy(wxCommandEvent &event);
void on_axis_ctrl_z_up_10(wxCommandEvent &event);
void on_axis_ctrl_z_up_1(wxCommandEvent &event);