![](/media/cache/img/default_profile.jpg.50x50_q85.jpg)
For coursework of group 3 in SOFT564Z
Dependencies: Motordriver ros_lib_kinetic
ROS_Handler.cpp
- Committer:
- Jonathan738
- Date:
- 2020-01-05
- Revision:
- 12:82b8fe254222
- Parent:
- 11:0b9098ec11c7
File content as of revision 12:82b8fe254222:
#include "mbed.h" #include "General.hpp" #include "ros.h" #include "rtos.h" #include "ROS_Handler.hpp" #include <motordriver.h> #include "math.h" #include "Motors.hpp" #include "Pins.h" #include "VL6180.hpp" extern Motor A; // pwm, fwd, rev, can brake extern Motor B; // pwm, fwd, rev, can brake /******************************************************************************/ /* ROS serial hardware setup */ /******************************************************************************/ // Create the ROS node handle class HaseHardware : public MbedHardware { public: HaseHardware(): MbedHardware(ROS_Tx, ROS_Rx, ROS_BaudRate) {}; }; /******************************************************************************/ ros::NodeHandle_<HaseHardware> Node_; ros::Subscriber<std_msgs::Float32MultiArray> Control_Subscriber(Control_Topic, &Control_CallBack); std_msgs::String State_msg; std_msgs::String TOF_msg; ros::Publisher Status_PUB(Status_Topic, &State_msg); ros::Publisher TOF_PUB(TOF_Topic, &TOF_msg); extern Mutex Global_Battery_Level_Mutex; extern float Global_Battery_Level; extern float Global_Battery_Value; extern bool Battery_Update_Flag; extern int Global_TOF_Ranges[num_VL6180]; extern bool TOF_Range_Flag; extern Mutex Global_TOF_Range_Mutex; float LIN_Val, ANG_Val; Mutex Duty_Mutex; // Main function for thread to handle ROS comms void ROS_Handler(void){ LIN_Val = 0; ANG_Val = 0; Node_.initNode(); Node_.advertise(Status_PUB); Node_.advertise(TOF_PUB); Node_.subscribe(Control_Subscriber); while (1) { Global_Battery_Level_Mutex.lock(); if(Battery_Update_Flag == true) { float Battery_Level = Global_Battery_Level; float Battery_Value = Global_Battery_Value; Battery_Update_Flag = false; Global_Battery_Level_Mutex.unlock(); char buffer[50]; Duty_Mutex.lock(); sprintf(buffer, "Battery Level : %1.3f% | Battery Voltage %1.3fV | Linear Duty %1.3f | Angular Duty %1.3f |", (Battery_Level*100), Battery_Value, LIN_Val, ANG_Val); Duty_Mutex.unlock(); State_msg.data = buffer; Status_PUB.publish(&State_msg); } else { Global_Battery_Level_Mutex.unlock(); } Global_TOF_Range_Mutex.lock(); if(TOF_Range_Flag == true) { int TOF_Range[num_VL6180]; for(int IDX = 0; IDX < num_VL6180; IDX++) { TOF_Range[IDX] = Global_TOF_Ranges[IDX]; } TOF_Range_Flag = false; Global_TOF_Range_Mutex.unlock(); char buffer[50]; sprintf(buffer, "Range 1: %d | Range 2: %d | Range 3: %d | Range 4: %d", TOF_Range[0], TOF_Range[1], TOF_Range[2], TOF_Range[3]); TOF_msg.data = buffer; TOF_PUB.publish(&State_msg); } else { Global_TOF_Range_Mutex.unlock(); } Node_.spinOnce(); wait_ms(20); } } int Remap(float value, float start1, float stop1, float start2, float stop2) { return (int)(start2 + (stop2 - start2) * ((value - start1) / (stop1 - start1))); } void Control_CallBack(const std_msgs::Float32MultiArray& cmd_vel_msg) { /**************************************************************************/ //Extracting the only commands that will be used in the multiarray, and assuming that the int value attached to each point is 100 times //the intended PWM constant for that movement command (e.g. a value of 50 in msg.data[6] would give a PWM duty cycle of 0.5 for rotation): float xlin, zang; if((cmd_vel_msg.data[0] <= 1.0f) && (cmd_vel_msg.data[0] >= -1.0f)) { xlin = cmd_vel_msg.data[0]; Duty_Mutex.lock(); LIN_Val = xlin; Duty_Mutex.unlock();; } if((cmd_vel_msg.data[1] <= 1.0f) && (cmd_vel_msg.data[1] >= -1.0f)) { zang = cmd_vel_msg.data[1]; Duty_Mutex.lock(); ANG_Val = zang; Duty_Mutex.unlock(); } //assume rotation needs to be taken care of first, generally, then linear movement for this basic controller //assume positive z is clockwise, negative is anticlockwise, A is left motor, B is right motor (viewed from bottom layer battery switch direction) if(zang == 0.0f && xlin == 0.0f) { A.stop(0.5f); B.stop(0.5f); wait(1); A.coast(); B.coast(); } else if(zang != 0.0f && xlin !=0.0f) { // Needs testing A.speed((-xlin + zang)/2.0f); B.speed((-xlin + -zang)/2.0f); } else if(xlin != 0) { A.speed(-xlin); B.speed(-xlin); } else if(zang != 0) { A.speed(zang); B.speed(-zang); } /**************************************************************************/ }