Prototyp V2
Dependencies: PM2_Libary
Diff: main.cpp
- Branch:
- lupo2
- Revision:
- 96:06f43e78d121
- Parent:
- 88:cb8a18fc0391
- Parent:
- 85:fbcc3d8e945a
diff -r cb8a18fc0391 -r 06f43e78d121 main.cpp --- a/main.cpp Mon May 02 14:47:17 2022 +0200 +++ b/main.cpp Wed May 04 09:24:35 2022 +0200 @@ -10,8 +10,8 @@ const float dist_arm_attach_distsensor = 20; // distance between pivot point arm on body to start distancesensor on top in horizontal (6) const float dist_distsensors = 200; // distance between the two distancesensors on top of Wall-E (9) const float dist_arm_ground = 51; // distance between pivotpoint arm and ground (5) -const float gripper_area_height = 16 ; // Height of Grappler cutout to grapple Stair (8) -const float dist_grappleratt_grappler_uk = 33; // distance between pivotpoint Grappler and bottom edge (?) +const float dist_arm_attach_OK_griparea = 10.5 ; // Height of Grappler cutout to grapple Stair (8) (maybe add 1mm so gripper is a bit over the plate) +const float dist_grappleratt_grappler_uk = 36.5; // distance between pivotpoint Grappler and bottom edge (?) const float height_stairs = 100; // height to top of next stairstep in mm //*********************************************************************************************************************************************************** @@ -69,161 +69,93 @@ // PositionController positionController_M3(counts_per_turn, kn, max_voltage, pwm_M3, encoder_M3); // default 78.125:1 gear with default contoller parameters //PositionController positionController_M3(counts_per_turn * k_gear, kn / k_gear, kp * k_gear, max_voltage, pwm_M3, encoder_M3); // parameters adjusted to 100:1 gear, we need a different speed controller gain here //*********************************************************************************************************************************************************** -// logic functions for basic movement +// calculations for basic movment and controll //placeholder variables for prototype testing -const int drive_stright_mm = 100; // placeholder for testing drives amount forward -const int drive_back_mm = -100; // placeholder for testing drives amount backwards -int ToNextFunction = 0; // current state of the system (which function is beeing executed) +const int drive_straight_mm = 200; // placeholder for testing drives amount forward +const int drive_back_mm = -200; // placeholder for testing drives amount backwards +int ToNextFunction = 0; // current state of the system (which function is beeing executed) int state=0; - +// definition variables for calculations +const float pi = 2 * acos(0.0); // definiton of pi +const float end_pos_lift_deg = 180 + asin((dist_arm_ground-(dist_grappleratt_grappler_uk))/arm_length) * 180 / pi; // calculates the degree which the arm has to have when lift_up has been executed. +const float start_deg_arm = -asin((dist_arm_ground - dist_grappleratt_grappler_uk) / arm_length) * 180.0/pi ; //calculates the starting degree of the arm (gripper has to touch ground in frotn of Wall-E) -// definition important variables -const float pi = 2 * acos(0.0); // definiton of pi +// definition of rotation speeds for motors 0 = none 1.0 = max. const float max_speed_rps_wheel = 0.5f; // define maximum speed that the position controller is changig the speed for the wheels, has to be smaller or equal to kn * max_voltage const float max_speed_rps_arm = 0.3f; // define maximum speed that the position controller is changig the speed for the arm, has to be smaller or equal to kn * max_voltage -float start_deg_arm = -asin((dist_arm_ground - dist_grappleratt_grappler_uk) / arm_length) * 180.0/pi ; ///calculates the starting degree of the arm (gripper has to touch ground in frotn of Wall-E) -// import functions from file mapping -extern double powerx(double base, double pow2); -extern double mapping (float adc_value_mV); // calculates the deg which the arm has to take to reach a certain height (the input height has to be the height of OK Gripper area) +// PARAM: height_mm = height which OK Gripperarea has to reach. +// RETURN: deg_arm = absolut Position in deg that the arm has to take. float calc_arm_deg_for_height(int height_mm) { - float deg_arm; - if ((height_mm - dist_arm_ground - (dist_grappleratt_grappler_uk - gripper_area_height)) > arm_length) //check if height is reachable - { - printf("Error in calc_arm_deg_for_height: desired height is bigger than Wall-E arm lenght."); // error message when desired height is not reachable. - } - else - { - float height_arm = height_mm - dist_arm_ground - (dist_grappleratt_grappler_uk - gripper_area_height); // calculates the height which only the arm has to cover (- attachement height (arm to robot) etc.) - deg_arm = asin(height_arm / arm_length) * 180.0/pi; // calculates the absolute degrees which the arm has to reach - } + float height_arm = height_mm - (dist_arm_ground - dist_arm_attach_OK_griparea); // calculates the height which only the arm has to cover (- attachement height (arm to robot) etc.) + float deg_arm = asin(height_arm / arm_length) * 180.0/pi; // calculates the absolute degrees which the arm has to reach return deg_arm; } +//calculates the deg which the wheels have to turn in order to cover specified distance in mm +//PARAM: distance = distance to drive in milimeter +//RETURN: deg_wheel = degree which the motor has to turn in order to cover distance(mm) +float wheel_dist_to_deg(int distance) +{ + float deg_wheel = distance / (wheel_diameter * pi) * 360; + return deg_wheel; +} + + +// increments the Motor for defined degree from the current one +// PARAM: deg_to_turn = degree to turn the Motor +// PARAM: current_rotation = the current rotation of the Motor (Motor.getRotation()) +// RETURN: new_turn_rotation = new Rotation value in rotations +float turn_relative_deg(float deg_to_turn, float current_rotation) +{ + float new_turn_rotation = current_rotation + deg_to_turn/360.0; + return new_turn_rotation; +} + +// sets the Motor to a specified degree in one rotation +// PARAM: end_deg = new position of the arm in degree 0 <= value >=360 +// PARAM: current_rotation = the current rotation of the Motor (Motor.getRotation()) +// RETURN: new_partial_rotation = new deg value in rotations +float turn_absolut_deg(float end_deg, float current_rotations) +{ + int full_rotations; + if(current_rotations > 0) + { + full_rotations = round(current_rotations - 0.5); + } + else if(current_rotations < 0) + { + full_rotations = round(current_rotations + 0.5); + } + else + { + full_rotations = 0; + } + float new_partial_rotation = full_rotations - start_deg_arm/360 + end_deg/360; + return new_partial_rotation; +} + //calculates position of arm when lift up has ended. //RETURN: end_deg = degree which the motor has to turn in order to reach end lift position. float calc_pos_end_lift() { float end_deg; - end_deg = asin((dist_arm_ground-(dist_grappleratt_grappler_uk-gripper_area_height))/arm_length) + start_deg_arm; + end_deg = asin((dist_arm_ground-(dist_grappleratt_grappler_uk-dist_grappleratt_grappler_uk))/arm_length) + start_deg_arm; end_deg = end_deg * 180 / pi; return end_deg; } -//calculates the deg which the wheels have to turn in order to cover specified distance in mm -//RETURN: deg_wheel = degree which the motor has to turn in order to cover distance(mm) -float wheel_dist_to_deg(int distance) // distance has to be in mm. -{ - float deg_wheel = distance * 360 /(wheel_diameter * pi); - return deg_wheel; -} - -// increments the Motor for defined degree from the current one -// PARAM: deg_to_turn = degree to turn the Motor -// PARAM: current_full_rotation = the current rotation of the Motor (Motor.getRotation()) -// RETURN: new Rotation value in rotations -float turn_relative_deg(float deg_to_turn, float current_full_rotation) -{ - float current_rotations = current_full_rotation; - float new_turn_rotation = current_rotations - deg_to_turn/360.0; - return new_turn_rotation; -} - -// sets the Motor to a specified degree in one rotation -// PARAM: end_deg = new position of the arm in degree 0 <= value >=360 -// PARAM: current_rotations = the current rotation of the Motor (Motor.getRotation()) -// RETURN: new_partial_rotation = new deg value in rotations -float turn_absolut_deg(float end_deg, float current_rotations) -{ - int full_rotations = current_rotations; - float new_partial_rotation = current_rotations - start_deg_arm/360; - return new_partial_rotation; -} - -// bring arm in starting position. Height of stairs. -int set_arm_stair_height() -{ - float diff; - double deg_up_from_horizon = calc_arm_deg_for_height(height_stairs); //deg which arm motor has to turn to in order to grab stair. starting from horizontal position - float deg = deg_up_from_horizon + start_deg_arm; - if ((0.0 > deg) || (deg > 360.0)) - { - printf("Error in start_position: degree is out of bound for Start Position."); // error when desired reaching point is out of reach. - return 2; - } - - enable_motors = 1; - positionController_M_Arm.setDesiredRotation(deg / 360.0, max_speed_rps_arm); // command to turn motor to desired deg. - - diff = deg-(positionController_M_Arm.getRotation() * 360.0); - if (diff<=0.3){ - return 1; - } - else { - return NULL;} - - - enable_motors = 0; +//*********************************************************************************************************************************************************** +// important calculatet constant for Wall-E +const double deg_up_from_horizon_to_stair = calc_arm_deg_for_height(height_stairs); -} - -//Drives forward into the next step -//Prameter:distance in milimeter -int drive_straight(float distance) -{ - float diff_R; - float diff_L; - float deg_to_turn = wheel_dist_to_deg(distance); - float relativ_turns_rightmotor = turn_relative_deg(deg_to_turn, positionController_M_right.getRotation()); - float relativ_turns_leftmotor = turn_relative_deg(deg_to_turn, positionController_M_left.getRotation()); - - enable_motors = 1; - positionController_M_right.setDesiredRotation(relativ_turns_rightmotor, max_speed_rps_wheel); - positionController_M_left.setDesiredRotation(relativ_turns_leftmotor, max_speed_rps_wheel); - enable_motors = 0; - - diff_R= relativ_turns_rightmotor-positionController_M_right.getRotation(); - diff_L= relativ_turns_leftmotor-positionController_M_left.getRotation(); - if ((diff_R<=0.3) && (diff_L<=0.3)) - { - return 1; - } - else - { - return 0; - } -} - -//only turns the arm until the robot is on the next step -int lift_up() -{ - float diff; - float position_lift_end_deg = asin((-dist_arm_ground - (dist_grappleratt_grappler_uk-gripper_area_height)) / arm_length) - 90; // calculates the degree which has to be reached in order to get on top of next step - float relativ_turns_arm = turn_absolut_deg(position_lift_end_deg, positionController_M_Arm.getRotation()); - - enable_motors = 1; - positionController_M_Arm.setDesiredRotation(relativ_turns_arm , max_speed_rps_arm); - enable_motors = 0; - - diff=relativ_turns_arm-positionController_M_Arm.getRotation(); - if(diff<=0.3) - { return 1; - } - else - { return 0; - } - - -} -//*********************************************************************************************************************************************************** - -int NextStep (float){ - return 1; -} +// import functions from file mapping +extern double powerx(double base, double pow2); +extern double mapping (float adc_value_mV); // //simple check if there is an object in proximity @@ -239,11 +171,92 @@ else return 2; } -//Function which checks if sensors and motors have been wired correctly and the expectet results will happen. otherwise Wall-E will show with armmovement. -void check_start() +//simple check if there is an object in proximity +//returns 0 if there is NO object present +//returns 1 if there is an object present +//returns 2 if the distance isn't in the expected range +uint8_t StepDetection_down(float sensor) + +{ + double d_valueMM = mapping(sensor*1.0e3f*3.3f); + if(d_valueMM >= 4) return 0; + else if(d_valueMM < 4) return 1; + else if(d_valueMM <= 0 || d_valueMM > 100 ) return 2; + else return 2; +} + +// bring arm in starting position. Height of stairs. +int set_arm_stair_height() + +{ + float deg = deg_up_from_horizon_to_stair + start_deg_arm; + float diff; + double deg_up_from_horizon = calc_arm_deg_for_height(height_stairs); //deg which arm motor has to turn to in order to grab stair. starting from horizontal position + positionController_M_Arm.setDesiredRotation(deg / 360.0, max_speed_rps_arm); // command to turn motor to desired deg. + diff = deg-(positionController_M_Arm.getRotation() * 360.0); + if (diff<=0.3){ + return 1; + } + else { + return NULL;} +} + +//Drives forward into the next step +//Prameter:distance in milimeter +int drive_straight(float distance) { + float diff_R; + float diff_L; + float deg_to_turn = wheel_dist_to_deg(distance); + float relativ_turns_rightmotor = turn_relative_deg(deg_to_turn, positionController_M_right.getRotation()); + float relativ_turns_leftmotor = turn_relative_deg(deg_to_turn, positionController_M_left.getRotation()); + + + positionController_M_right.setDesiredRotation(relativ_turns_rightmotor, max_speed_rps_wheel); + positionController_M_left.setDesiredRotation(relativ_turns_leftmotor, max_speed_rps_wheel); + + + diff_R= relativ_turns_rightmotor-positionController_M_right.getRotation(); + diff_L= relativ_turns_leftmotor-positionController_M_left.getRotation(); + if ((diff_R<=0.3) && (diff_L<=0.3)) + { + return 1; + } + else + { + return 0; + } +} + +//turns the arm until the robot is on the next step +int lift_up() +{ + float diff; + float absolut_pos_arm = turn_absolut_deg(end_pos_lift_deg, positionController_M_Arm.getRotation()-1); + float position_lift_end_deg = asin((-dist_arm_ground - (dist_grappleratt_grappler_uk-dist_arm_attach_OK_griparea)) / arm_length) - 90; // calculates the degree which has to be reached in order to get on top of next step + float relativ_turns_arm = turn_absolut_deg(position_lift_end_deg, positionController_M_Arm.getRotation()); + + + positionController_M_Arm.setDesiredRotation(relativ_turns_arm , max_speed_rps_arm); + + diff=relativ_turns_arm-positionController_M_Arm.getRotation(); + if(diff<=0.3) + { return 1; + } + else + { return 0; + } } +//*********************************************************************************************************************************************************** +//Function which checks if sensors and motors have been wired correctly and the expectet results will happen. otherwise Wall-E will show with armmovement. +void check_start(); + +int NextStep (float){ + return 1; +} + + // while loop gets executed every main_task_period_ms milliseconds int main_task_period_ms = 30; // define main task period time in ms e.g. 30 ms -> main task runns ~33,33 times per second @@ -259,21 +272,26 @@ while (true) { + ir_distance_mm_L= mapping(ir_analog_in_Distance_L.read()*1.0e3f * 3.3f); ir_distance_mm_R= mapping(ir_analog_in_Distance_R.read()*1.0e3f * 3.3f); - ir_distance_mm_Lookdown_B= mapping(ir_analog_in_Lookdown_B.read()*1.0e3f * 3.3f); - ir_distance_mm_Lookdown_F= mapping(ir_analog_in_Lookdown_F.read()*1.0e3f * 3.3f); + + if (ToNextFunction>=1) + { + enable_motors=1; + } switch (ToNextFunction) { case 1: - set_arm_stair_height(); + state=set_arm_stair_height(); printf("Case 1: Position ARM (rot): %3.3f\n",positionController_M_Arm.getRotation()); if (state==1){ ToNextFunction += 1; } + break; case 2: @@ -283,13 +301,13 @@ } case 3: - state=drive_straight(drive_stright_mm); + state=drive_straight(drive_straight_mm); printf("Case 2: Position Right(rot): %3.3f; Position Left (rot): %3.3f\n", positionController_M_right.getRotation(),positionController_M_left.getRotation()); if (state==1){ ToNextFunction += 1; } - break; + case 4: state=lift_up(); @@ -298,7 +316,6 @@ ToNextFunction += 1; } - case 5: state=drive_straight(drive_back_mm); printf("Case 4: Position Right(rot): %3.3f; Position Left (rot): %3.3f\n", @@ -315,13 +332,14 @@ ToNextFunction = 1; } break; + default: ; } } - // read timer and make the main thread sleep for the remaining time span (non blocking) - int main_task_elapsed_time_ms = std::chrono::duration_cast<std::chrono::milliseconds>(main_task_timer.elapsed_time()).count(); - thread_sleep_for(main_task_period_ms - main_task_elapsed_time_ms); - return 0; + // read timer and make the main thread sleep for the remaining time span (non blocking) + int main_task_elapsed_time_ms = std::chrono::duration_cast<std::chrono::milliseconds>(main_task_timer.elapsed_time()).count(); + thread_sleep_for(main_task_period_ms - main_task_elapsed_time_ms); + return 0; }