Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include "hFramework.h"
- //#include "hCloudClient.h"
- #include "ros.h"
- #include "std_msgs/Int16.h"
- #include "std_msgs/Float32.h"
- #include "std_msgs/UInt16MultiArray.h"
- #include "std_msgs/Empty.h"
- #include "std_msgs/Bool.h"
- #include "sensor_msgs/JointState.h"
- #include "geometry_msgs/TwistStamped.h"
- #include "geometry_msgs/Vector3Stamped.h"
- #include "std_srvs/Trigger.h"
- #include "diff_controller.h"
- #include "params.h"
- #include "utils.h"
- #include "config.h"
- #include "imu.h"
- using namespace hFramework;
- ros::NodeHandle nh;
- std_msgs::Float32 battery;
- ros::Publisher *battery_pub;
- bool publish_battery = false;
- geometry_msgs::TwistStamped odom;
- ros::Publisher *odom_pub;
- bool publish_odom = false;
- sensor_msgs::JointState joint_states;
- ros::Publisher *joint_states_pub;
- bool publish_joint = false;
- IMU* imu;
- geometry_msgs::Vector3Stamped imu_gyro_msg;
- ros::Publisher *imu_gyro_pub;
- geometry_msgs::Vector3Stamped imu_accel_msg;
- ros::Publisher *imu_accel_pub;
- geometry_msgs::Vector3Stamped imu_mag_msg;
- ros::Publisher *imu_mag_pub;
- bool publish_imu = false;
- // <<<
- std_msgs::Float32 gpio_in_msg;
- ros::Publisher *gpio_in_pub;
- bool publish_gpio_in = false;
- ros::Subscriber<std_msgs::Bool> *gpio_out_sub;
- // >>>
- ros::Subscriber<geometry_msgs::Twist> *twist_sub;
- ros::Subscriber<std_msgs::Empty> *reset_board_sub;
- ros::Subscriber<std_msgs::Empty> *reset_config_sub;
- ros::Subscriber<std_msgs::Bool> *set_imu_sub;
- ros::ServiceServer<std_srvs::TriggerRequest, std_srvs::TriggerResponse>* imu_cal_mpu_srv;
- ros::ServiceServer<std_srvs::TriggerRequest, std_srvs::TriggerResponse>* imu_cal_mag_srv;
- DiffController *dc;
- ServoWrapper servo1(1, hServo.servo1);
- ServoWrapper servo2(2, hServo.servo2);
- ServoWrapper servo3(3, hServo.servo3);
- ServoWrapper servo4(4, hServo.servo4);
- ServoWrapper servo5(5, hServo.servo5);
- ServoWrapper servo6(6, hServo.servo6);
- void cmdVelCallback(const geometry_msgs::Twist& msg)
- {
- dc->setSpeed(msg.linear.x, msg.angular.z);
- #ifdef DEBUG
- Serial.printf("[cmdVelCallback] linear: %f angular %f\r\n", msg.linear.x, msg.angular.z);
- #endif
- }
- void resetBoardCallback(const std_msgs::Empty& msg)
- {
- sys.reset();
- }
- void resetConfigCallback(const std_msgs::Empty& msg)
- {
- reset_config();
- }
- void setImuCallback(const std_msgs::Bool& msg)
- {
- conf.imu_enabled = msg.data;
- store_config();
- }
- void calMpuCallback(const std_srvs::TriggerRequest& req, std_srvs::TriggerResponse& res)
- {
- imu->calGyroAccel();
- res.message = "Succesfully calibrated gyroscope and accelerometer biases";
- res.success = true;
- }
- void calMagCallback(const std_srvs::TriggerRequest& req, std_srvs::TriggerResponse& res)
- {
- imu->calMag();
- res.message = "Succesfully calibrated magnetometer";
- res.success = true;
- }
- // <<<
- void GPIOOutCallback(const std_msgs::Bool& msg)
- {
- hExt.pin3.write(msg.data);
- }
- // >>>
- void initROS()
- {
- battery_pub = new ros::Publisher("/battery", &battery);
- odom_pub = new ros::Publisher("/wheel_odom", &odom);
- joint_states_pub = new ros::Publisher("/joint_states", &joint_states);
- twist_sub = new ros::Subscriber<geometry_msgs::Twist>("cmd_vel", &cmdVelCallback);
- reset_board_sub = new ros::Subscriber<std_msgs::Empty>("core2/reset_board", &resetBoardCallback);
- reset_config_sub = new ros::Subscriber<std_msgs::Empty>("core2/reset_config", &resetConfigCallback);
- set_imu_sub = new ros::Subscriber<std_msgs::Bool>("core2/set_imu", &setImuCallback);
- ros::Subscriber<std_msgs::Int16, ServoWrapper> *servo1_angle_sub =
- new ros::Subscriber<std_msgs::Int16, ServoWrapper>("servo1/angle", &ServoWrapper::angleCallback, &servo1);
- ros::Subscriber<std_msgs::Int16, ServoWrapper> *servo2_angle_sub =
- new ros::Subscriber<std_msgs::Int16, ServoWrapper>("servo2/angle", &ServoWrapper::angleCallback, &servo2);
- ros::Subscriber<std_msgs::Int16, ServoWrapper> *servo3_angle_sub =
- new ros::Subscriber<std_msgs::Int16, ServoWrapper>("servo3/angle", &ServoWrapper::angleCallback, &servo3);
- ros::Subscriber<std_msgs::Int16, ServoWrapper> *servo4_angle_sub =
- new ros::Subscriber<std_msgs::Int16, ServoWrapper>("servo4/angle", &ServoWrapper::angleCallback, &servo4);
- ros::Subscriber<std_msgs::Int16, ServoWrapper> *servo5_angle_sub =
- new ros::Subscriber<std_msgs::Int16, ServoWrapper>("servo5/angle", &ServoWrapper::angleCallback, &servo5);
- ros::Subscriber<std_msgs::Int16, ServoWrapper> *servo6_angle_sub =
- new ros::Subscriber<std_msgs::Int16, ServoWrapper>("servo6/angle", &ServoWrapper::angleCallback, &servo6);
- ros::Subscriber<std_msgs::UInt16MultiArray, ServoWrapper> *servo1_pwm_sub =
- new ros::Subscriber<std_msgs::UInt16MultiArray, ServoWrapper>("servo1/pwm", &ServoWrapper::pwmCallback, &servo1);
- ros::Subscriber<std_msgs::UInt16MultiArray, ServoWrapper> *servo2_pwm_sub =
- new ros::Subscriber<std_msgs::UInt16MultiArray, ServoWrapper>("servo2/pwm", &ServoWrapper::pwmCallback, &servo2);
- ros::Subscriber<std_msgs::UInt16MultiArray, ServoWrapper> *servo3_pwm_sub =
- new ros::Subscriber<std_msgs::UInt16MultiArray, ServoWrapper>("servo3/pwm", &ServoWrapper::pwmCallback, &servo3);
- ros::Subscriber<std_msgs::UInt16MultiArray, ServoWrapper> *servo4_pwm_sub =
- new ros::Subscriber<std_msgs::UInt16MultiArray, ServoWrapper>("servo4/pwm", &ServoWrapper::pwmCallback, &servo4);
- ros::Subscriber<std_msgs::UInt16MultiArray, ServoWrapper> *servo5_pwm_sub =
- new ros::Subscriber<std_msgs::UInt16MultiArray, ServoWrapper>("servo5/pwm", &ServoWrapper::pwmCallback, &servo5);
- ros::Subscriber<std_msgs::UInt16MultiArray, ServoWrapper> *servo6_pwm_sub =
- new ros::Subscriber<std_msgs::UInt16MultiArray, ServoWrapper>("servo6/pwm", &ServoWrapper::pwmCallback, &servo6);
- nh.advertise(*battery_pub);
- nh.advertise(*odom_pub);
- nh.advertise(*joint_states_pub);
- nh.subscribe(*twist_sub);
- nh.subscribe(*reset_board_sub);
- nh.subscribe(*reset_config_sub);
- nh.subscribe(*set_imu_sub);
- nh.subscribe(*servo1_angle_sub);
- nh.subscribe(*servo2_angle_sub);
- nh.subscribe(*servo3_angle_sub);
- nh.subscribe(*servo4_angle_sub);
- nh.subscribe(*servo5_angle_sub);
- nh.subscribe(*servo6_angle_sub);
- nh.subscribe(*servo1_pwm_sub);
- nh.subscribe(*servo2_pwm_sub);
- nh.subscribe(*servo3_pwm_sub);
- nh.subscribe(*servo4_pwm_sub);
- nh.subscribe(*servo5_pwm_sub);
- nh.subscribe(*servo6_pwm_sub);
- if (conf.imu_enabled)
- {
- imu_gyro_pub = new ros::Publisher("/imu/gyro", &imu_gyro_msg);
- imu_accel_pub = new ros::Publisher("/imu/accel", &imu_accel_msg);
- imu_mag_pub = new ros::Publisher("/imu/mag", &imu_mag_msg);
- imu_cal_mpu_srv = new ros::ServiceServer<std_srvs::TriggerRequest, std_srvs::TriggerResponse>
- ("imu/calibrate_gyro_accel", &calMpuCallback);
- imu_cal_mag_srv = new ros::ServiceServer<std_srvs::TriggerRequest, std_srvs::TriggerResponse>
- ("imu/calibrate_mag", &calMagCallback);
- nh.advertise(*imu_gyro_pub);
- nh.advertise(*imu_accel_pub);
- nh.advertise(*imu_mag_pub);
- nh.advertiseService<std_srvs::TriggerRequest, std_srvs::TriggerResponse>(*imu_cal_mpu_srv);
- nh.advertiseService<std_srvs::TriggerRequest, std_srvs::TriggerResponse>(*imu_cal_mag_srv);
- }
- // <<<
- gpio_in_pub = new ros::Publisher("/gpio_in", &gpio_in_msg);
- gpio_out_sub = new ros::Subscriber<std_msgs::Bool>("/gpio_out", &GPIOOutCallback);
- nh.advertise(*gpio_in_pub);
- nh.subscribe(*gpio_out_sub);
- // >>>
- }
- void setupServos()
- {
- hServo.enablePower();
- hServo.setPeriod(SERVO_PERIOD);
- switch(SERVO_VOLTAGE) {
- case VOLTAGE_5V:
- hServo.setVoltage5V();
- break;
- case VOLTAGE_6V:
- hServo.setVoltage6V();
- break;
- case VOLTAGE_7V4:
- hServo.setVoltage7V4();
- break;
- case VOLTAGE_8V6:
- hServo.setVoltage8V6();
- }
- hServo.servo1.calibrate(SERVO_1_ANGLE_MIN, SERVO_1_WIDTH_MIN,
- SERVO_1_ANGLE_MAX, SERVO_1_WIDTH_MAX);
- hServo.servo2.calibrate(SERVO_2_ANGLE_MIN, SERVO_2_WIDTH_MIN,
- SERVO_2_ANGLE_MAX, SERVO_2_WIDTH_MAX);
- hServo.servo3.calibrate(SERVO_3_ANGLE_MIN, SERVO_3_WIDTH_MIN,
- SERVO_3_ANGLE_MAX, SERVO_3_WIDTH_MAX);
- hServo.servo4.calibrate(SERVO_4_ANGLE_MIN, SERVO_4_WIDTH_MIN,
- SERVO_4_ANGLE_MAX, SERVO_4_WIDTH_MAX);
- hServo.servo5.calibrate(SERVO_5_ANGLE_MIN, SERVO_5_WIDTH_MIN,
- SERVO_5_ANGLE_MAX, SERVO_5_WIDTH_MAX);
- hServo.servo6.calibrate(SERVO_6_ANGLE_MIN, SERVO_6_WIDTH_MIN,
- SERVO_6_ANGLE_MAX, SERVO_6_WIDTH_MAX);
- }
- void setupJoints()
- {
- joint_states.header.frame_id = "base_link";
- joint_states.name = new char*[4] {
- "wheel_FL_joint", "wheel_RL_joint",
- "wheel_FR_joint", "wheel_RR_joint"
- };
- joint_states.position = new float[4];
- joint_states.velocity = new float[4];
- joint_states.effort = new float[4];
- joint_states.name_length = 4;
- joint_states.position_length = 4;
- joint_states.velocity_length = 4;
- joint_states.effort_length = 4;
- }
- void setupImu()
- {
- IMU_HSENS.selectI2C();
- imu = new IMU(IMU_HSENS.getI2C());
- imu->begin();
- imu_gyro_msg.header.frame_id = "imu";
- imu_accel_msg.header.frame_id = "imu";
- imu_mag_msg.header.frame_id = "imu";
- }
- void setupOdom()
- {
- odom.header.frame_id = "base_link";
- }
- void batteryLoop()
- {
- uint32_t t = sys.getRefTime();
- long dt = 1000;
- while(true)
- {
- if (!publish_battery)
- {
- battery.data = sys.getSupplyVoltage();
- publish_battery = true;
- }
- sys.delaySync(t, dt);
- }
- }
- void odomLoop()
- {
- uint32_t t = sys.getRefTime();
- long dt = 50;
- while(true)
- {
- if (!publish_odom)
- {
- odom.header.stamp = nh.now();
- std::vector<float> odo = dc->getOdom();
- odom.twist.linear.x = odo[0];
- odom.twist.angular.z = odo[1];
- publish_odom = true;
- }
- sys.delaySync(t, dt);
- }
- }
- void jointStatesLoop()
- {
- uint32_t t = sys.getRefTime();
- long dt = 50;
- while(true)
- {
- if (!publish_joint)
- {
- std::vector<float> pos = dc->getWheelPositions();
- std::vector<float> vel = dc->getWheelVelocities();
- std::vector<float> eff = dc->getWheelEfforts();
- joint_states.header.stamp = nh.now();
- joint_states.position[0] = pos[0];
- joint_states.position[1] = pos[1];
- joint_states.position[2] = pos[2];
- joint_states.position[3] = pos[3];
- joint_states.velocity[0] = vel[0];
- joint_states.velocity[1] = vel[1];
- joint_states.velocity[2] = vel[2];
- joint_states.velocity[3] = vel[3];
- joint_states.effort[0] = eff[0];
- joint_states.effort[1] = eff[1];
- joint_states.effort[2] = eff[2];
- joint_states.effort[3] = eff[3];
- publish_joint = true;
- }
- sys.delaySync(t, dt);
- }
- }
- void imuLoop()
- {
- uint32_t t = sys.getRefTime();
- long dt = 25;
- while(true)
- {
- imu->update();
- ros::Time stamp = nh.now();
- imu_gyro_msg.header.stamp = stamp;
- imu_gyro_msg.vector.x = imu->gx;
- imu_gyro_msg.vector.y = imu->gy;
- imu_gyro_msg.vector.z = imu->gz;
- imu_accel_msg.header.stamp = stamp;
- imu_accel_msg.vector.x = imu->ax;
- imu_accel_msg.vector.y = imu->ay;
- imu_accel_msg.vector.z = imu->az;
- imu_mag_msg.header.stamp = stamp;
- imu_mag_msg.vector.x = imu->mx;
- imu_mag_msg.vector.y = imu->my;
- imu_mag_msg.vector.z = imu->mz;
- publish_imu = true;
- sys.delaySync(t, dt);
- }
- }
- void LEDLoop()
- {
- uint32_t t = sys.getRefTime();
- long dt = 250;
- while(true)
- {
- if(!nh.connected())
- LED.toggle();
- else
- LED.write(true);
- sys.delaySync(t, dt);
- }
- }
- // <<<
- void GPIOInLoop()
- {
- uint32_t t = sys.getRefTime();
- long dt = 100;
- while(true)
- {
- if (!publish_gpio_in)
- {
- gpio_in_msg.data = hExt.pin2.analogReadVoltage();
- publish_gpio_in = true;
- }
- sys.delaySync(t, dt);
- }
- }
- // >>>
- void hMain()
- {
- uint32_t t = sys.getRefTime();
- //platform.begin(&RPi);
- //nh.getHardware()->initWithDevice(&platform.LocalSerial);
- RPi.setBaudrate(250000);
- nh.getHardware()->initWithDevice(&RPi);
- nh.initNode();
- dc = new DiffController(INPUT_TIMEOUT);
- dc->start();
- load_config();
- // <<<
- hExt.pin2.enableADC();
- hExt.pin3.setOut();
- // >>>
- setupOdom();
- setupServos();
- setupJoints();
- initROS();
- // <<<
- sys.taskCreate(&GPIOInLoop);
- // >>>
- sys.setLogDev(&Serial);
- LED.setOut();
- sys.taskCreate(&LEDLoop);
- sys.taskCreate(&batteryLoop);
- sys.taskCreate(&odomLoop);
- sys.taskCreate(&jointStatesLoop);
- if (conf.imu_enabled)
- {
- setupImu();
- sys.taskCreate(&imuLoop);
- }
- while (true)
- {
- nh.spinOnce();
- if (nh.connected())
- {
- if (publish_battery){
- battery_pub->publish(&battery);
- publish_battery = false;
- }
- if (publish_odom){
- odom_pub->publish(&odom);
- publish_odom = false;
- }
- if (publish_joint){
- joint_states_pub->publish(&joint_states);
- publish_joint = false;
- }
- if (publish_imu){
- imu_gyro_pub->publish(&imu_gyro_msg);
- imu_accel_pub->publish(&imu_accel_msg);
- imu_mag_pub->publish(&imu_mag_msg);
- publish_imu = false;
- }
- // <<<
- if (publish_gpio_in){
- gpio_in_pub->publish(&gpio_in_msg);
- publish_gpio_in = false;
- }
- // >>>
- }
- sys.delaySync(t, 1);
- }
- }
RAW Paste Data