For YRL Robot Arm
robotarm.cpp
- Committer:
- jah128
- Date:
- 2017-03-03
- Revision:
- 0:b14dfd8816da
File content as of revision 0:b14dfd8816da:
/* University of York Robotics Laboratory Robot Arm Controller Board * * Robot Arm Controller * * File: robotarm.cpp * * (C) Dept. Electronics & Computer Science, University of York * * James Hilder, Alan Millard, Shuhei Miyashita, Homero Elizondo, Jon Timmis * * February 2017, Version 1.0 */ #include "robotarm.h" Display display; //Connects to i2c(p28,p27) Remote remote; Serial pc(USBTX,USBRX); Servo servo(p9,p10); short target_base = 2048; short target_shoulder = 2048; short target_elbow = 2048; short target_wrist = 2048; void Robotarm::init() { pc.baud(115200); //hardware_test(); pc.printf("Robot Arm Controller\nSoftware Version %1.2f\n",SOFTWARE_VERSION_CODE); display.init(); init_servos(); } void Robotarm::init_servos() { Timeout fail_timeout; fail_timeout.attach(this,&Robotarm::fail_init,2); display.clear_display(); wait(0.1); display.set_position(0,0); display.write_string("CHECKING SERVOS:"); pc.printf("Initialising robot arm\n"); wait(0.1); if(HAS_BASE) { display.set_position(1,0); display.write_string("BASE:"); pc.printf("Check servo %d [BASE]:",BASE); if(servo.GetModelNumber(BASE) != MX28_MODEL) fail_init(); servo.SetLowVoltageLimit(BASE, LOW_VOLTAGE_LIMIT); servo.SetHighVoltageLimit(BASE, HIGH_VOLTAGE_LIMIT); servo.SetTemperatureLimit(BASE, HIGH_TEMPERATURE_LIMIT); //servo.SetCWLimit(BASE, 0); //servo.SetCCWLimit(BASE, 0); servo.LockEeprom(BASE); pc.printf("OK\n"); display.set_position(1,9); display.write_string("[OK]"); wait(0.2); } if(HAS_SHOULDER) { display.set_position(1,0); display.write_string("SHOULDER: "); pc.printf("Check servo %d [SHOULDER]:",SHOULDER); if(servo.GetModelNumber(SHOULDER) != MX28_MODEL) fail_init(); servo.SetLowVoltageLimit(SHOULDER, LOW_VOLTAGE_LIMIT); servo.SetHighVoltageLimit(SHOULDER, HIGH_VOLTAGE_LIMIT); servo.SetTemperatureLimit(SHOULDER, HIGH_TEMPERATURE_LIMIT); //servo.SetCWLimit(SHOULDER, 0); //servo.SetCCWLimit(SHOULDER, 0); servo.LockEeprom(SHOULDER); pc.printf("OK\n"); display.set_position(1,9); display.write_string("[OK]"); wait(0.2); } if(HAS_ELBOW) { display.set_position(1,0); display.write_string("ELBOW: "); pc.printf("Check servo %d [ELBOW]:",ELBOW); if(servo.GetModelNumber(ELBOW) != MX28_MODEL) fail_init(); servo.SetLowVoltageLimit(ELBOW, LOW_VOLTAGE_LIMIT); servo.SetHighVoltageLimit(ELBOW, HIGH_VOLTAGE_LIMIT); servo.SetTemperatureLimit(ELBOW, HIGH_TEMPERATURE_LIMIT); //servo.SetCWLimit(ELBOW, 0); //servo.SetCCWLimit(ELBOW, 0); servo.LockEeprom(ELBOW); pc.printf("OK\n"); display.set_position(1,9); display.write_string("[OK]"); wait(0.2); } if(HAS_WRIST) { display.set_position(1,0); display.write_string("WRIST: "); pc.printf("Check servo %d [WRIST]:",WRIST); if(servo.GetModelNumber(WRIST) != AX12_MODEL) fail_init(); servo.SetLowVoltageLimit(WRIST, LOW_VOLTAGE_LIMIT); servo.SetHighVoltageLimit(WRIST, HIGH_VOLTAGE_LIMIT); servo.SetTemperatureLimit(WRIST, HIGH_TEMPERATURE_LIMIT); //servo.SetCWLimit(WRIST, 0); //servo.SetCCWLimit(WRIST, 0); servo.LockEeprom(WRIST); pc.printf("OK\n"); display.set_position(1,9); display.write_string("[OK]"); wait(0.2); } fail_timeout.detach(); } float zero_time_delay; Timeout zero_timeout; void Robotarm::zero_servos(float time_delay) { if(time_delay <= 0)_zero_servos(); else { zero_time_delay = time_delay; display.clear_display(); display.set_position(0,0); display.write_string("ZEROING ARM IN"); display.set_position(1,0); char message[17]; sprintf(message,"%2.1f SECONDS",zero_time_delay); display.write_string(message); if(zero_time_delay < 0.1)zero_timeout.attach(this,&Robotarm::_zero_servos,zero_time_delay); else zero_timeout.attach(this,&Robotarm::_zero_servos_display_update,0.1); } } void Robotarm::_zero_servos_display_update() { display.set_position(1,0); zero_time_delay-=0.1; char message[17]; sprintf(message,"%2.1f SECONDS",zero_time_delay); display.write_string(message); if(zero_time_delay < 0.1) zero_timeout.attach(this,&Robotarm::_zero_servos,zero_time_delay); else zero_timeout.attach(this,&Robotarm::_zero_servos_display_update,0.1); } void Robotarm::_zero_servos() { display.clear_display(); servo.SetGoal(BASE,2048,1); servo.SetGoal(SHOULDER,2048,1); servo.SetGoal(ELBOW,2048,1); servo.trigger(); target_base = 2048; target_shoulder = 2048; target_elbow = 2048; target_wrist = 2048; } void Robotarm::fail_init() { display.clear_display(); display.set_position(0,0); display.write_string("SERVO ERROR"); while(1) { remote.set_led(1); wait(0.2); remote.set_led(0); wait(0.1); } } void Robotarm::hardware_test() { pc.printf("\nBeginning extended hardware test\n"); wait(0.5); pc.printf("Scanning for servos:\n"); servo.ScanForServos(); pc.printf("\nDone."); while(1); } // Important: initialise_servo() is ONLY used when setting the servo IDs for the first time, // do not run once the arm has been set up! void Robotarm::initialise_servo(int target_servo) { pc.printf("RUNNING SERVO SETUP ROUTINE FOR SERVO %d\n\n",target_servo); // MX-28s default to a baud rate of 57600 with delay time of 500us servo.SetInitBaud(57600, 250); int model = servo.GetModelNumber(1); if(model != MX28_MODEL) { pc.printf("Error: No MX-28 servo with ID 1 found...\n"); while(1); } servo.DebugData(1); pc.printf("\n\nSetting up MX-28 servo to ID %d\n",target_servo); servo.SetID(0x01,target_servo); wait(0.25); //Uncomment the following block to setup servo to use 1Mbps baud rate /* pc.printf("Setting baud rate for servo to 1000000\n"); servo.SetBaud(target_servo,1); wait(0.25); pc.printf("Setting return delay time for servo to %dus\n",RETURN_DELAY + RETURN_DELAY); servo.SetDelayTime(target_servo,RETURN_DELAY); wait(0.25); pc.printf("Resetting connecting baud rate\n"); servo.SetInitBaud(1000000, RETURN_DELAY); wait(0.25); */ pc.printf("Getting servo data:\n"); servo.DebugData(target_servo); while(0.25); } /* * Copyright 2016 University of York * * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and limitations under the License. * */