|
|
|
|
@ -174,12 +174,16 @@ void cb_posctl_change_entry (GtkWidget *widget, gpointer data) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* draw position relative to target position.
|
|
|
|
|
* draw the axis vectors form the center of the screen.
|
|
|
|
|
* draw the earch movement to the center of the screen.
|
|
|
|
|
*/
|
|
|
|
|
void cb_posctl_angles_draw(GtkWidget *area, cairo_t *cr, int w, int h, gpointer data) {
|
|
|
|
|
int clientw, clienth;
|
|
|
|
|
|
|
|
|
|
position_f_2d lpos[5];
|
|
|
|
|
float lmax;
|
|
|
|
|
position_f_2d lpos, p;
|
|
|
|
|
position_2d center;
|
|
|
|
|
double pscale = 2.0;
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// rotation da
|
|
|
|
|
@ -199,10 +203,6 @@ void cb_posctl_angles_draw(GtkWidget *area, cairo_t *cr, int w, int h, gpointer
|
|
|
|
|
|
|
|
|
|
if (posctl_rot_da == NULL) // should only be called once
|
|
|
|
|
posctl_rot_da = GTK_WIDGET(gtk_builder_get_object (GTK_BUILDER(_builder_), "posctl_da_rotation"));
|
|
|
|
|
if (posctl_axis1_da == NULL) // should only be called once
|
|
|
|
|
posctl_axis1_da = GTK_WIDGET(gtk_builder_get_object (GTK_BUILDER(_builder_), "posctl_da_rotation"));
|
|
|
|
|
if (posctl_axis2_da == NULL) // should only be called once
|
|
|
|
|
posctl_axis2_da = GTK_WIDGET(gtk_builder_get_object (GTK_BUILDER(_builder_), "posctl_da_rotation"));
|
|
|
|
|
clienth = gtk_widget_get_allocated_height(posctl_rot_da);
|
|
|
|
|
clientw = gtk_widget_get_allocated_width(posctl_rot_da);
|
|
|
|
|
center.x = clientw >> 1;
|
|
|
|
|
@ -228,69 +228,83 @@ void cb_posctl_angles_draw(GtkWidget *area, cairo_t *cr, int w, int h, gpointer
|
|
|
|
|
cairo_stroke(cr);
|
|
|
|
|
cairo_set_dash(cr, NULL, 0, 0);
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// calculate angles
|
|
|
|
|
lpos[0].x = sin(rotangle) * rotlen;
|
|
|
|
|
lpos[0].y = cos(rotangle) * rotlen;
|
|
|
|
|
|
|
|
|
|
lpos[1].x = lpos[0].x + sin(a1_angle) * a1_len;
|
|
|
|
|
lpos[1].y = lpos[0].y + cos(a1_angle) * a1_len;
|
|
|
|
|
lpos[2].x = lpos[0].x;
|
|
|
|
|
lpos[2].y = lpos[0].y;
|
|
|
|
|
|
|
|
|
|
lpos[3].x = lpos[0].x + sin(a2_angle) * a2_len;
|
|
|
|
|
lpos[3].y = lpos[0].y + cos(a2_angle) * a2_len;
|
|
|
|
|
lpos[4].x = lpos[0].x;
|
|
|
|
|
lpos[4].y = lpos[0].y;
|
|
|
|
|
|
|
|
|
|
// find maximum
|
|
|
|
|
for (int i = 0; i < 5; i++) {
|
|
|
|
|
if (i == 0) {
|
|
|
|
|
lmax = fabs (lpos[0].x);
|
|
|
|
|
if (fabs(lpos[i].y) > lmax) lmax = fabs(lpos[i].y);
|
|
|
|
|
} else {
|
|
|
|
|
if (fabs(lpos[i].x) > lmax) lmax = fabs(lpos[i].x);
|
|
|
|
|
if (fabs(lpos[i].y) > lmax) lmax = fabs(lpos[i].y);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// draw
|
|
|
|
|
cairo_select_font_face (cr, "sans-serif", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL);
|
|
|
|
|
cairo_set_font_size (cr, 11);
|
|
|
|
|
cairo_set_line_width(cr, 4.0);
|
|
|
|
|
|
|
|
|
|
// rot
|
|
|
|
|
lpos.x = -sin(rotangle) * rotlen * 4.0;
|
|
|
|
|
lpos.y = -cos(rotangle) * rotlen * 4.0;
|
|
|
|
|
cairo_set_source_rgb(cr, 0.0, 0.0, 0.0);
|
|
|
|
|
cairo_set_line_width(cr, 4.0);
|
|
|
|
|
cairo_move_to(cr, center.x, center.y);
|
|
|
|
|
cairo_line_to(cr, center.x + float (lpos[0].x * center.x * 0.8 / lmax),
|
|
|
|
|
center.y - float (lpos[0].y * center.y * 0.8 / lmax));
|
|
|
|
|
cairo_line_to(cr, center.x + lpos.x, center.y + lpos.y);
|
|
|
|
|
cairo_stroke(cr);
|
|
|
|
|
cairo_set_line_width(cr, 0.5);
|
|
|
|
|
cairo_move_to(cr, center.x - lpos.x * 100.0, center.y - lpos.y * 100.0);
|
|
|
|
|
cairo_line_to(cr, center.x + lpos.x * 100.0, center.y + lpos.y * 100.0);
|
|
|
|
|
cairo_stroke(cr);
|
|
|
|
|
cairo_move_to(cr, center.x + float (lpos[0].x * center.x * 0.9 / lmax),
|
|
|
|
|
center.y - float (lpos[0].y * center.y * 0.9 / lmax));
|
|
|
|
|
cairo_show_text(cr, (char *)"E");
|
|
|
|
|
|
|
|
|
|
// axis1
|
|
|
|
|
cairo_set_source_rgb(cr, 0.0, 1.0, 0.5);
|
|
|
|
|
cairo_move_to(cr, center.x + float (lpos[1].x * center.x * 0.8 / lmax),
|
|
|
|
|
center.y - float (lpos[1].y * center.y * 0.8 / lmax));
|
|
|
|
|
cairo_line_to(cr, center.x + float (lpos[2].x * center.x * 0.8 / lmax),
|
|
|
|
|
center.y - float (lpos[2].y * center.y * 0.8 / lmax));
|
|
|
|
|
lpos.x = sin(a1_angle) * a1_len * 4.0;
|
|
|
|
|
lpos.y = cos(a1_angle) * a1_len * 4.0;
|
|
|
|
|
cairo_set_source_rgb(cr, 0.0, 0.75, 0.3);
|
|
|
|
|
cairo_set_line_width(cr, 4.0);
|
|
|
|
|
cairo_move_to(cr, center.x, center.y);
|
|
|
|
|
cairo_line_to(cr, center.x + lpos.x, center.y + lpos.y);
|
|
|
|
|
cairo_stroke(cr);
|
|
|
|
|
cairo_set_line_width(cr, 0.5);
|
|
|
|
|
cairo_move_to(cr, center.x - lpos.x * 100.0, center.y - lpos.y * 100.0);
|
|
|
|
|
cairo_line_to(cr, center.x + lpos.x * 100.0, center.y + lpos.y * 100.0);
|
|
|
|
|
cairo_stroke(cr);
|
|
|
|
|
cairo_move_to(cr, center.x + float (lpos[1].x * center.x * 0.9 / lmax),
|
|
|
|
|
center.y - float (lpos[1].y * center.y * 0.9 / lmax));
|
|
|
|
|
cairo_show_text(cr, (char *)"1");
|
|
|
|
|
|
|
|
|
|
// axis2
|
|
|
|
|
cairo_set_source_rgb(cr, 0.0, 0.5, 1.0);
|
|
|
|
|
cairo_move_to(cr, center.x + float (lpos[3].x * center.x * 0.8 / lmax),
|
|
|
|
|
center.y - float (lpos[3].y * center.y * 0.8 / lmax));
|
|
|
|
|
cairo_line_to(cr, center.x + float (lpos[4].x * center.x * 0.8 / lmax),
|
|
|
|
|
center.y - float (lpos[4].y * center.y * 0.8 / lmax));
|
|
|
|
|
lpos.x = sin(a2_angle) * a2_len * 4.0;
|
|
|
|
|
lpos.y = cos(a2_angle) * a2_len * 4.0;
|
|
|
|
|
cairo_set_source_rgb(cr, 0.0, 0.3, 0.75);
|
|
|
|
|
cairo_set_line_width(cr, 4.0);
|
|
|
|
|
cairo_move_to(cr, center.x, center.y);
|
|
|
|
|
cairo_line_to(cr, center.x + lpos.x, center.y + lpos.y);
|
|
|
|
|
cairo_stroke(cr);
|
|
|
|
|
cairo_set_line_width(cr, 0.5);
|
|
|
|
|
cairo_move_to(cr, center.x - lpos.x * 100.0, center.y - lpos.y * 100.0);
|
|
|
|
|
cairo_line_to(cr, center.x + lpos.x * 100.0, center.y + lpos.y * 100.0);
|
|
|
|
|
cairo_stroke(cr);
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// draw position relative to the target
|
|
|
|
|
p = posctl.current_pos - posctl.target_pos;
|
|
|
|
|
p.x *= pscale;
|
|
|
|
|
p.y *= pscale;
|
|
|
|
|
cairo_set_source_rgb(cr, 0.8, 0.1, 0.1);
|
|
|
|
|
cairo_set_line_width(cr, 1.0);
|
|
|
|
|
cairo_move_to(cr, center.x-4 + p.x, center.y + p.y);
|
|
|
|
|
cairo_line_to(cr, center.x+4 + p.x, center.y + p.y);
|
|
|
|
|
cairo_stroke(cr);
|
|
|
|
|
cairo_move_to(cr, center.x + p.x, center.y-4 + p.y);
|
|
|
|
|
cairo_line_to(cr, center.x + p.x, center.y+4 + p.y);
|
|
|
|
|
cairo_stroke(cr);
|
|
|
|
|
cairo_move_to(cr, center.x+4 + p.x, center.y-4 + p.y);
|
|
|
|
|
cairo_line_to(cr, center.x-4 + p.x, center.y+4 + p.y);
|
|
|
|
|
cairo_stroke(cr);
|
|
|
|
|
cairo_move_to(cr, center.x+4 + p.x, center.y+4 + p.y);
|
|
|
|
|
cairo_line_to(cr, center.x-4 + p.x, center.y-4 + p.y);
|
|
|
|
|
cairo_stroke(cr);
|
|
|
|
|
|
|
|
|
|
// draw distance to axis
|
|
|
|
|
lpos.x = sindeg(posctl.calib_axis1.a) * posctl.axis_pv[0] * pscale;
|
|
|
|
|
lpos.y = cosdeg(posctl.calib_axis1.a) * posctl.axis_pv[0] * pscale;
|
|
|
|
|
cairo_move_to(cr, center.x + p.x, center.y + p.y);
|
|
|
|
|
cairo_line_to(cr, center.x + p.x + lpos.x, center.y + p.y + lpos.y);
|
|
|
|
|
cairo_stroke(cr);
|
|
|
|
|
|
|
|
|
|
// draw distance to axis
|
|
|
|
|
lpos.x = sindeg(posctl.calib_axis2.a) * posctl.axis_pv[1] * pscale;
|
|
|
|
|
lpos.y = cosdeg(posctl.calib_axis2.a) * posctl.axis_pv[1] * pscale;
|
|
|
|
|
cairo_move_to(cr, center.x + p.x, center.y + p.y);
|
|
|
|
|
cairo_line_to(cr, center.x + p.x + lpos.x, center.y + p.y + lpos.y);
|
|
|
|
|
cairo_stroke(cr);
|
|
|
|
|
cairo_move_to(cr, center.x + float (lpos[3].x * center.x * 0.9 / lmax),
|
|
|
|
|
center.y - float (lpos[3].y * center.y * 0.9 / lmax));
|
|
|
|
|
cairo_show_text(cr, (char *)"2");
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -307,6 +321,7 @@ void cb_posctl_entryanglelen (GtkWidget *widget, gpointer data) {
|
|
|
|
|
void cb_posctl_axis_draw(GtkWidget *area, cairo_t *cr, int w, int h, gpointer data) {
|
|
|
|
|
GtkWidget *da1 = GTK_WIDGET(gtk_builder_get_object (GTK_BUILDER(_builder_), "posctl_da_axis1"));
|
|
|
|
|
GtkWidget *da2 = GTK_WIDGET(gtk_builder_get_object (GTK_BUILDER(_builder_), "posctl_da_axis2"));
|
|
|
|
|
|
|
|
|
|
position_2d center;
|
|
|
|
|
int axis = 0 , i, cnt;
|
|
|
|
|
double dx, dy;
|
|
|
|
|
@ -346,7 +361,7 @@ void cb_posctl_axis_draw(GtkWidget *area, cairo_t *cr, int w, int h, gpointer da
|
|
|
|
|
cairo_set_source_rgb(cr, 1.0, 0.5, 0.5);
|
|
|
|
|
cairo_select_font_face (cr, "sans-serif", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL);
|
|
|
|
|
cairo_set_font_size (cr, 10);
|
|
|
|
|
cairo_move_to(cr, 00, 10);
|
|
|
|
|
cairo_move_to(cr, 10, 10);
|
|
|
|
|
cairo_show_text(cr, (char *)"diff");
|
|
|
|
|
// draw elements diff
|
|
|
|
|
i = axis_history_pos[axis];
|
|
|
|
|
@ -370,10 +385,11 @@ void cb_posctl_axis_draw(GtkWidget *area, cairo_t *cr, int w, int h, gpointer da
|
|
|
|
|
} while (i != axis_history_pos[axis]);
|
|
|
|
|
cairo_stroke(cr);
|
|
|
|
|
|
|
|
|
|
cairo_set_source_rgb(cr, 0.0, 1.0, 0.5);
|
|
|
|
|
if (axis == 0) cairo_set_source_rgb(cr, 0.0, 0.75, 0.3);
|
|
|
|
|
else cairo_set_source_rgb(cr, 0.0, 0.3, 0.75);
|
|
|
|
|
cairo_select_font_face (cr, "sans-serif", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL);
|
|
|
|
|
cairo_set_font_size (cr, 10);
|
|
|
|
|
cairo_move_to(cr, 40, 10);
|
|
|
|
|
cairo_move_to(cr, 60, 10);
|
|
|
|
|
cairo_show_text(cr, (char *)"out");
|
|
|
|
|
// draw elements diff
|
|
|
|
|
i = axis_history_pos[axis];
|
|
|
|
|
@ -396,10 +412,6 @@ void cb_posctl_axis_draw(GtkWidget *area, cairo_t *cr, int w, int h, gpointer da
|
|
|
|
|
if (i < 0) i = AXIS_HISTORY_CNT-1;
|
|
|
|
|
} while (i != axis_history_pos[axis]);
|
|
|
|
|
cairo_stroke(cr);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// draw chart
|
|
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -559,8 +571,11 @@ gboolean cb_thread_posctl (gpointer data) {
|
|
|
|
|
|
|
|
|
|
gtk_widget_queue_draw(da1);
|
|
|
|
|
gtk_widget_queue_draw(da2);
|
|
|
|
|
if (posctl_axis1_da) gdk_window_invalidate_rect(gtk_widget_get_window(posctl_axis1_da), NULL, true);
|
|
|
|
|
if (posctl_axis2_da) gdk_window_invalidate_rect(gtk_widget_get_window(posctl_axis2_da), NULL, true);
|
|
|
|
|
|
|
|
|
|
if (posctl_rot_da == NULL) // should only be called once
|
|
|
|
|
posctl_rot_da = GTK_WIDGET(gtk_builder_get_object (GTK_BUILDER(_builder_), "posctl_da_rotation"));
|
|
|
|
|
gdk_window_invalidate_rect(gtk_widget_get_window(posctl_rot_da), NULL, true);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
};
|
|
|
|
|
@ -570,8 +585,7 @@ PosCtl::PosCtl() {
|
|
|
|
|
mode = POSCTL_MODE_OFF;
|
|
|
|
|
|
|
|
|
|
#ifdef DEBUG_POSCTL
|
|
|
|
|
debug_tofile((char*)"posctl.log", (char*)"\n");
|
|
|
|
|
debug_tofile((char*)"posctl.log", (char*)"mode,posX,posY,targetX,targetY,dx,dy,axis1.pv,axis1.op,axis1.kp,axis1.ki,axis1.kd,axis2.pv,axis2.op,axis2.kp,axis2.ki,axis2.kd\n");
|
|
|
|
|
debug_tofile((char*)"posctl.log", 1, (char*)"mode , calEV,calEL , posX,posY,targetX,targetY,dx,dy , cal1V,cal1L , axis1.pv,axis1.op,axis1.kp,axis1.ki,axis1.kd , cal2V,cal2L , axis2.pv,axis2.op,axis2.kp,axis2.ki,axis2.kd\n");
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
calib_mode = POSCTL_CALIB_MODE_OFF;
|
|
|
|
|
@ -673,7 +687,7 @@ void PosCtl::CalibModeDelta(int x, int y) {
|
|
|
|
|
pid_axis[0].GetParam(&a1min, &a1max, NULL, NULL, NULL);
|
|
|
|
|
|
|
|
|
|
fp.x = (x - calib_pos.x) / (float)timediff;
|
|
|
|
|
fp.y = -(y - calib_pos.y) / (float)timediff;
|
|
|
|
|
fp.y = (y - calib_pos.y) / (float)timediff;
|
|
|
|
|
|
|
|
|
|
LockMutex();
|
|
|
|
|
calib_rot_v = fp;
|
|
|
|
|
@ -704,7 +718,7 @@ void PosCtl::CalibModeAxis(int x, int y) {
|
|
|
|
|
printf ("%s:%d %s calib_mode: %d\n", __FILE__, __LINE__, __FUNCTION__, calib_mode);
|
|
|
|
|
|
|
|
|
|
fp.x = +(x - calib_pos.x) / timediff;
|
|
|
|
|
fp.y = -(y - calib_pos.y) / timediff;
|
|
|
|
|
fp.y = +(y - calib_pos.y) / timediff;
|
|
|
|
|
|
|
|
|
|
if (calib_mode == POSCTL_CALIB_MODE_AXIS1) {
|
|
|
|
|
calib_axis1_v = fp - calib_rot_v;
|
|
|
|
|
@ -745,7 +759,7 @@ void PosCtl::Loop (int posx, int posy) {
|
|
|
|
|
static int lastmode = -1;
|
|
|
|
|
double kp0,ki0,kd0, kp1,ki1,kd1;
|
|
|
|
|
if (lastmode != mode && mode != POSCTL_MODE_CONTROL) {
|
|
|
|
|
debug_tofile((char*)"posctl.log", (char*)"%d,,,,,,,,,,,,,,,,\n", mode);
|
|
|
|
|
debug_tofile((char*)"posctl.log", 0, (char*)"%d,,,,,,,,,,,,,,,,,,,,,,\n", mode);
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
//
|
|
|
|
|
@ -781,13 +795,14 @@ void PosCtl::Loop (int posx, int posy) {
|
|
|
|
|
// dist_axis1 --> will control pid_axis2
|
|
|
|
|
// dist_axis2 --> will control pis_axis1
|
|
|
|
|
else if (mode == POSCTL_MODE_CONTROL) {
|
|
|
|
|
position_f_2d p;
|
|
|
|
|
position_f_2d p, target_p;
|
|
|
|
|
|
|
|
|
|
LockMutex();
|
|
|
|
|
|
|
|
|
|
// calculate
|
|
|
|
|
// dist_axis < 0.0 pid should increase the output.
|
|
|
|
|
// > 0.0 pid should decrease the output
|
|
|
|
|
target_p.x = target_pos.x; target_p.y = target_pos.y;
|
|
|
|
|
p.x = posx; p.y = posy;
|
|
|
|
|
axis_pv[0] = calib_axis2_v.perpendicular(p, target_pos);
|
|
|
|
|
axis_pv[1] = calib_axis1_v.perpendicular(p, target_pos);
|
|
|
|
|
@ -797,13 +812,14 @@ void PosCtl::Loop (int posx, int posy) {
|
|
|
|
|
#ifdef DEBUG_POSCTL
|
|
|
|
|
pid_axis[0].GetParam(NULL, NULL, &kp0, &ki0, &kd0);
|
|
|
|
|
pid_axis[1].GetParam(NULL, NULL, &kp1, &ki1, &kd1);
|
|
|
|
|
debug_tofile((char*)"posctl.log", (char*)"%d,%d,%d,%d,%d,%d,%d,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g\n",
|
|
|
|
|
mode, posx, posy, target_pos.x, target_pos.y, posx - target_pos.x, posy - target_pos.y,
|
|
|
|
|
axis_pv[0], axis_op[0],kp0,ki0,kd0,
|
|
|
|
|
axis_pv[1], axis_op[1],kp1,ki1,kd1);
|
|
|
|
|
debug_tofile((char*)"posctl.log", 0, (char*)"%d , %g,%g , %d,%d,%g,%g,%g,%g , %g,%g , %g,%g,%g,%g,%g , %g,%g , %g,%g,%g,%g,%g\n",
|
|
|
|
|
mode, calib_rot.a, calib_rot.l,
|
|
|
|
|
posx, posy, target_pos.x, target_pos.y, posx - target_pos.x, posy - target_pos.y,
|
|
|
|
|
calib_axis1.a, calib_axis1.l, axis_pv[0], axis_op[0],kp0,ki0,kd0,
|
|
|
|
|
calib_axis2.a, calib_axis2.l, axis_pv[1], axis_op[1],kp1,ki1,kd1);
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
if (OutputWriteValue(0, axis_op[0]) || OutputWriteValue(1, axis_op[1]))
|
|
|
|
|
if (OutputWriteValue(0, axis_op[0]) || OutputWriteValue(1, axis_op[1]))
|
|
|
|
|
mode = POSCTL_MODE_OFF;
|
|
|
|
|
|
|
|
|
|
axis_history_add(0, axis_pv[0], axis_op[0]);
|
|
|
|
|
@ -820,6 +836,8 @@ void PosCtl::Loop (int posx, int posy) {
|
|
|
|
|
UnLockMutex();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
current_pos.x = posx;
|
|
|
|
|
current_pos.y = posy;
|
|
|
|
|
#ifdef DEBUG_POSCTL
|
|
|
|
|
lastmode = mode;
|
|
|
|
|
#endif
|
|
|
|
|
|