|
|
|
@ -39,7 +39,9 @@
@@ -39,7 +39,9 @@
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
#include <px4_config.h> |
|
|
|
|
#include <platforms/px4_defines.h> |
|
|
|
|
#include <px4_getopt.h> |
|
|
|
|
#include <px4_defines.h> |
|
|
|
|
#include <px4_log.h> |
|
|
|
|
|
|
|
|
|
#include <stdio.h> |
|
|
|
|
#include <stdlib.h> |
|
|
|
@ -52,15 +54,9 @@
@@ -52,15 +54,9 @@
|
|
|
|
|
#include <sys/ioctl.h> |
|
|
|
|
#include <sys/stat.h> |
|
|
|
|
|
|
|
|
|
#include <nuttx/i2c.h> |
|
|
|
|
#include <nuttx/mtd.h> |
|
|
|
|
#include <nuttx/fs/nxffs.h> |
|
|
|
|
#include <nuttx/fs/ioctl.h> |
|
|
|
|
|
|
|
|
|
#include <arch/board/board.h> |
|
|
|
|
|
|
|
|
|
#include "systemlib/systemlib.h" |
|
|
|
|
#include "systemlib/err.h" |
|
|
|
|
#include "drivers/drv_pwm_output.h" |
|
|
|
|
|
|
|
|
|
#include <uORB/topics/actuator_controls.h> |
|
|
|
@ -76,9 +72,9 @@ static void
@@ -76,9 +72,9 @@ static void
|
|
|
|
|
usage(const char *reason) |
|
|
|
|
{ |
|
|
|
|
if (reason != NULL) |
|
|
|
|
warnx("%s", reason); |
|
|
|
|
PX4_ERR("%s", reason); |
|
|
|
|
|
|
|
|
|
errx(1, |
|
|
|
|
PX4_ERR( |
|
|
|
|
"usage:\n" |
|
|
|
|
"esc_calib\n" |
|
|
|
|
" [-d <device> PWM output device (defaults to " PWM_OUTPUT0_DEVICE_PATH ")\n" |
|
|
|
@ -93,7 +89,7 @@ usage(const char *reason)
@@ -93,7 +89,7 @@ usage(const char *reason)
|
|
|
|
|
int |
|
|
|
|
esc_calib_main(int argc, char *argv[]) |
|
|
|
|
{ |
|
|
|
|
char *dev = PWM_OUTPUT0_DEVICE_PATH; |
|
|
|
|
const char *dev = PWM_OUTPUT0_DEVICE_PATH; |
|
|
|
|
char *ep; |
|
|
|
|
int ch; |
|
|
|
|
int ret; |
|
|
|
@ -114,21 +110,24 @@ esc_calib_main(int argc, char *argv[])
@@ -114,21 +110,24 @@ esc_calib_main(int argc, char *argv[])
|
|
|
|
|
|
|
|
|
|
if (argc < 2) { |
|
|
|
|
usage("no channels provided"); |
|
|
|
|
return 1; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
int arg_consumed = 0; |
|
|
|
|
|
|
|
|
|
while ((ch = getopt(argc, argv, "d:c:m:al:h:")) != EOF) { |
|
|
|
|
int myoptind = 1; |
|
|
|
|
const char *myoptarg = NULL; |
|
|
|
|
while ((ch = px4_getopt(argc, argv, "d:c:m:al:h:", &myoptind, &myoptarg)) != EOF) { |
|
|
|
|
switch (ch) { |
|
|
|
|
|
|
|
|
|
case 'd': |
|
|
|
|
dev = optarg; |
|
|
|
|
dev = myoptarg; |
|
|
|
|
arg_consumed += 2; |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
case 'c': |
|
|
|
|
/* Read in channels supplied as one int and convert to mask: 1234 -> 0xF */ |
|
|
|
|
channels = strtoul(optarg, &ep, 0); |
|
|
|
|
channels = strtoul(myoptarg, &ep, 0); |
|
|
|
|
|
|
|
|
|
while ((single_ch = channels % 10)) { |
|
|
|
|
|
|
|
|
@ -139,9 +138,11 @@ esc_calib_main(int argc, char *argv[])
@@ -139,9 +138,11 @@ esc_calib_main(int argc, char *argv[])
|
|
|
|
|
|
|
|
|
|
case 'm': |
|
|
|
|
/* Read in mask directly */ |
|
|
|
|
set_mask = strtoul(optarg, &ep, 0); |
|
|
|
|
if (*ep != '\0') |
|
|
|
|
set_mask = strtoul(myoptarg, &ep, 0); |
|
|
|
|
if (*ep != '\0') { |
|
|
|
|
usage("bad set_mask value"); |
|
|
|
|
return 1; |
|
|
|
|
} |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
case 'a': |
|
|
|
@ -153,27 +154,34 @@ esc_calib_main(int argc, char *argv[])
@@ -153,27 +154,34 @@ esc_calib_main(int argc, char *argv[])
|
|
|
|
|
|
|
|
|
|
case 'l': |
|
|
|
|
/* Read in custom low value */ |
|
|
|
|
pwm_low = strtoul(optarg, &ep, 0); |
|
|
|
|
if (*ep != '\0' || pwm_low < PWM_LOWEST_MIN || pwm_low > PWM_HIGHEST_MIN) |
|
|
|
|
pwm_low = strtoul(myoptarg, &ep, 0); |
|
|
|
|
if (*ep != '\0' || pwm_low < PWM_LOWEST_MIN || pwm_low > PWM_HIGHEST_MIN) { |
|
|
|
|
usage("low PWM invalid"); |
|
|
|
|
return 1; |
|
|
|
|
} |
|
|
|
|
break; |
|
|
|
|
case 'h': |
|
|
|
|
/* Read in custom high value */ |
|
|
|
|
pwm_high = strtoul(optarg, &ep, 0); |
|
|
|
|
if (*ep != '\0' || pwm_high > PWM_HIGHEST_MAX || pwm_high < PWM_LOWEST_MAX) |
|
|
|
|
pwm_high = strtoul(myoptarg, &ep, 0); |
|
|
|
|
if (*ep != '\0' || pwm_high > PWM_HIGHEST_MAX || pwm_high < PWM_LOWEST_MAX) { |
|
|
|
|
usage("high PWM invalid"); |
|
|
|
|
return 1; |
|
|
|
|
} |
|
|
|
|
break; |
|
|
|
|
default: |
|
|
|
|
usage(NULL); |
|
|
|
|
return 1; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (set_mask == 0) { |
|
|
|
|
usage("no channels chosen"); |
|
|
|
|
return 1; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (pwm_low > pwm_high) { |
|
|
|
|
usage("low pwm is higher than high pwm"); |
|
|
|
|
return 1; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* make sure no other source is publishing control values now */ |
|
|
|
@ -191,9 +199,10 @@ esc_calib_main(int argc, char *argv[])
@@ -191,9 +199,10 @@ esc_calib_main(int argc, char *argv[])
|
|
|
|
|
orb_check(act_sub, &orb_updated); |
|
|
|
|
|
|
|
|
|
if (orb_updated) { |
|
|
|
|
errx(1, "ABORTING! Attitude control still active. Please ensure to shut down all controllers:\n" |
|
|
|
|
PX4_ERR("ABORTING! Attitude control still active. Please ensure to shut down all controllers:\n" |
|
|
|
|
"\tmc_att_control stop\n" |
|
|
|
|
"\tfw_att_control stop\n"); |
|
|
|
|
return 1; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
printf("\nATTENTION, please remove or fix propellers before starting calibration!\n" |
|
|
|
@ -211,24 +220,22 @@ esc_calib_main(int argc, char *argv[])
@@ -211,24 +220,22 @@ esc_calib_main(int argc, char *argv[])
|
|
|
|
|
ret = poll(&fds, 1, 0); |
|
|
|
|
|
|
|
|
|
if (ret > 0) { |
|
|
|
|
|
|
|
|
|
read(0, &c, 1); |
|
|
|
|
|
|
|
|
|
if (c == 'y' || c == 'Y') { |
|
|
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
} else if (c == 0x03 || c == 0x63 || c == 'q') { |
|
|
|
|
printf("ESC calibration exited\n"); |
|
|
|
|
exit(0); |
|
|
|
|
return 0; |
|
|
|
|
|
|
|
|
|
} else if (c == 'n' || c == 'N') { |
|
|
|
|
printf("ESC calibration aborted\n"); |
|
|
|
|
exit(0); |
|
|
|
|
return 0; |
|
|
|
|
|
|
|
|
|
} else { |
|
|
|
|
printf("Unknown input, ESC calibration aborted\n"); |
|
|
|
|
exit(0); |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -239,24 +246,32 @@ esc_calib_main(int argc, char *argv[])
@@ -239,24 +246,32 @@ esc_calib_main(int argc, char *argv[])
|
|
|
|
|
/* open for ioctl only */ |
|
|
|
|
int fd = open(dev, 0); |
|
|
|
|
|
|
|
|
|
if (fd < 0) |
|
|
|
|
err(1, "can't open %s", dev); |
|
|
|
|
if (fd < 0) { |
|
|
|
|
PX4_ERR("can't open %s", dev); |
|
|
|
|
return 1; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* get number of channels available on the device */ |
|
|
|
|
ret = ioctl(fd, PWM_SERVO_GET_COUNT, (unsigned long)&max_channels); |
|
|
|
|
if (ret != OK) |
|
|
|
|
err(1, "PWM_SERVO_GET_COUNT"); |
|
|
|
|
if (ret != OK) { |
|
|
|
|
PX4_ERR("PWM_SERVO_GET_COUNT"); |
|
|
|
|
return 1; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* tell IO/FMU that its ok to disable its safety with the switch */ |
|
|
|
|
ret = ioctl(fd, PWM_SERVO_SET_ARM_OK, 0); |
|
|
|
|
if (ret != OK) |
|
|
|
|
err(1, "PWM_SERVO_SET_ARM_OK"); |
|
|
|
|
if (ret != OK) { |
|
|
|
|
PX4_ERR("PWM_SERVO_SET_ARM_OK"); |
|
|
|
|
return 1; |
|
|
|
|
} |
|
|
|
|
/* tell IO/FMU that the system is armed (it will output values if safety is off) */ |
|
|
|
|
ret = ioctl(fd, PWM_SERVO_ARM, 0); |
|
|
|
|
if (ret != OK) |
|
|
|
|
err(1, "PWM_SERVO_ARM"); |
|
|
|
|
if (ret != OK) { |
|
|
|
|
PX4_ERR("PWM_SERVO_ARM"); |
|
|
|
|
return 1; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
warnx("Outputs armed"); |
|
|
|
|
printf("Outputs armed"); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* wait for user confirmation */ |
|
|
|
@ -273,24 +288,24 @@ esc_calib_main(int argc, char *argv[])
@@ -273,24 +288,24 @@ esc_calib_main(int argc, char *argv[])
|
|
|
|
|
if (set_mask & 1<<i) { |
|
|
|
|
ret = ioctl(fd, PWM_SERVO_SET(i), pwm_high); |
|
|
|
|
|
|
|
|
|
if (ret != OK) |
|
|
|
|
err(1, "PWM_SERVO_SET(%d), value: %d", i, pwm_high); |
|
|
|
|
if (ret != OK) { |
|
|
|
|
PX4_ERR( "PWM_SERVO_SET(%d), value: %d", i, pwm_high); |
|
|
|
|
goto cleanup; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
ret = poll(&fds, 1, 0); |
|
|
|
|
|
|
|
|
|
if (ret > 0) { |
|
|
|
|
|
|
|
|
|
read(0, &c, 1); |
|
|
|
|
|
|
|
|
|
if (c == 13) { |
|
|
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
} else if (c == 0x03 || c == 0x63 || c == 'q') { |
|
|
|
|
warnx("ESC calibration exited"); |
|
|
|
|
exit(0); |
|
|
|
|
printf("ESC calibration exited"); |
|
|
|
|
goto done; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -310,24 +325,24 @@ esc_calib_main(int argc, char *argv[])
@@ -310,24 +325,24 @@ esc_calib_main(int argc, char *argv[])
|
|
|
|
|
if (set_mask & 1<<i) { |
|
|
|
|
ret = ioctl(fd, PWM_SERVO_SET(i), pwm_low); |
|
|
|
|
|
|
|
|
|
if (ret != OK) |
|
|
|
|
err(1, "PWM_SERVO_SET(%d), value: %d", i, pwm_low); |
|
|
|
|
if (ret != OK) { |
|
|
|
|
PX4_ERR("PWM_SERVO_SET(%d), value: %d", i, pwm_low); |
|
|
|
|
goto cleanup; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
ret = poll(&fds, 1, 0); |
|
|
|
|
|
|
|
|
|
if (ret > 0) { |
|
|
|
|
|
|
|
|
|
read(0, &c, 1); |
|
|
|
|
|
|
|
|
|
if (c == 13) { |
|
|
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
} else if (c == 0x03 || c == 0x63 || c == 'q') { |
|
|
|
|
printf("ESC calibration exited\n"); |
|
|
|
|
exit(0); |
|
|
|
|
goto done; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -337,12 +352,19 @@ esc_calib_main(int argc, char *argv[])
@@ -337,12 +352,19 @@ esc_calib_main(int argc, char *argv[])
|
|
|
|
|
|
|
|
|
|
/* disarm */ |
|
|
|
|
ret = ioctl(fd, PWM_SERVO_DISARM, 0); |
|
|
|
|
if (ret != OK) |
|
|
|
|
err(1, "PWM_SERVO_DISARM"); |
|
|
|
|
if (ret != OK) { |
|
|
|
|
PX4_ERR("PWM_SERVO_DISARM"); |
|
|
|
|
goto cleanup; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
warnx("Outputs disarmed"); |
|
|
|
|
printf("Outputs disarmed"); |
|
|
|
|
|
|
|
|
|
printf("ESC calibration finished\n"); |
|
|
|
|
|
|
|
|
|
exit(0); |
|
|
|
|
done: |
|
|
|
|
close(fd); |
|
|
|
|
return 0; |
|
|
|
|
cleanup: |
|
|
|
|
close(fd); |
|
|
|
|
return 1; |
|
|
|
|
} |
|
|
|
|