00001 /* 00002 * Copyright (c) 2011, A.M.Howard, S.Williams 00003 * All rights reserved. 00004 * 00005 * Redistribution and use in source and binary forms, with or without 00006 * modification, are permitted provided that the following conditions are met: 00007 * * Redistributions of source code must retain the above copyright 00008 * notice, this list of conditions and the following disclaimer. 00009 * * Redistributions in binary form must reproduce the above copyright 00010 * notice, this list of conditions and the following disclaimer in the 00011 * documentation and/or other materials provided with the distribution. 00012 * * Neither the name of the <organization> nor the 00013 * names of its contributors may be used to endorse or promote products 00014 * derived from this software without specific prior written permission. 00015 * 00016 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 00017 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 00018 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 00019 * DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY 00020 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 00021 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 00022 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 00023 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00024 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 00025 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00026 */ 00027 /* 00028 * example1_driver.cpp 00029 * 00030 * Created on: Nov 27, 2011 00031 * Author: Stephen Williams 00032 */ 00033 00034 #include <actuator_array_example/example1_driver.h> 00035 00036 namespace actuator_array_example 00037 { 00038 00039 /* ******************************************************** */ 00040 Example1Driver::Example1Driver() 00041 { 00042 // For normal drivers, you would read custom configuration settings from the parameter 00043 // server here. Common examples include the port name over which you are communicating, 00044 // or the baud rate for the serial port. For this very simple example, we don't actually 00045 // need any additional configuration. 00046 00047 // For this first, simple example, we will call the convenience init() script of the 00048 // base class. This sets up the list of joints, subscribes to needed topics, advertises 00049 // services, and calls the custom init_actuator_ function each actuator 00050 ActuatorArrayDriver::init(); 00051 00052 // Now create the array of simulated actuators 00053 for(unsigned int i = 0; i < command_msg_.name.size(); ++i) 00054 { 00055 // For this first, simple example we will use the default parameters for joint limits, 00056 // velocity, etc. provided by the DummyActuator Class 00057 actuators_[i] = DummyActuator(); 00058 } 00059 } 00060 00061 /* ******************************************************** */ 00062 Example1Driver::~Example1Driver() 00063 { 00064 } 00065 00066 /* ******************************************************** */ 00067 bool Example1Driver::read_(ros::Time ts) 00068 { 00069 // Calculate the time from the last update 00070 double dt = (ts - previous_time_).toSec(); 00071 00072 // Loop through each joint and request the current status 00073 // Note: The base class functions ensure the same joint order in 00074 // both the 'command' message and the 'joint_state' message 00075 for (unsigned int i = 0; i < joint_state_msg_.name.size(); ++i) 00076 { 00077 // Update the simulated state of each actuator by dt seconds 00078 actuators_[i].update(dt); 00079 00080 // Query the current state of each actuator 00081 joint_state_msg_.position[i] = actuators_[i].getPosition(); 00082 joint_state_msg_.velocity[i] = actuators_[i].getVelocity(); 00083 joint_state_msg_.effort[i] = actuators_[i].getMaxTorque(); 00084 } 00085 00086 joint_state_msg_.header.stamp = ts; 00087 previous_time_ = ts; 00088 00089 return true; 00090 } 00091 00092 /* ******************************************************** */ 00093 bool Example1Driver::command_() 00094 { 00095 // Loop through each joint in the command message and send the 00096 // corresponding servo the desired behavior 00097 for (unsigned int i = 0; i < command_msg_.name.size(); ++i) 00098 { 00099 actuators_[i].setVelocity(command_msg_.velocity[i]); 00100 actuators_[i].setPosition(command_msg_.position[i]); 00101 } 00102 00103 return true; 00104 } 00105 00106 /* ******************************************************** */ 00107 bool Example1Driver::stop_() 00108 { 00109 // Loop through each joint and send the stop command 00110 for (unsigned int i = 0; i < command_msg_.name.size(); ++i) 00111 { 00112 // Update the simulated state of each actuator by dt seconds 00113 actuators_[i].stop(); 00114 } 00115 00116 return true; 00117 } 00118 00119 /* ******************************************************** */ 00120 bool Example1Driver::home_() 00121 { 00122 // Loop through each joint and send the home command 00123 for (unsigned int i = 0; i < command_msg_.name.size(); ++i) 00124 { 00125 // Update the simulated state of each actuator by dt seconds 00126 actuators_[i].home(); 00127 } 00128 00129 return true; 00130 } 00131 00132 } // end namespace actuator_array_example 00133 00134 00135 00136 /* ******************************************************** */ 00137 int main(int argc, char** argv) 00138 { 00139 ros::init(argc, argv, "example1_driver"); 00140 00141 // Create an Example1 Driver Object 00142 actuator_array_example::Example1Driver driver; 00143 00144 // Put the driver in an infinite read-publish loop using the base class's 'spin' function 00145 driver.spin(); 00146 00147 return 0; 00148 }