Project

General

Profile

Revision 2814387f

ID2814387f48599dab8a99852093cc51629a14fb89

Added by Alex Zirbel over 12 years ago

Updated motors code.

Changed the definitions for the set_motors message, which forced a few
implementation changes as well.

Changed "libscout_node" to "node" and "n" to "node" in other packages.

View differences:

scout/libscout/src/constants.h
39 39

  
40 40
#include "ros/ros.h"
41 41

  
42
/* ROS defines */
43
#define QUEUE_SIZE 10
44

  
42 45
/* Libscout Defines */
43 46

  
44 47
/* Init defines */
scout/libscout/src/libbuttons.cpp
41 41

  
42 42

  
43 43
/* ROS node created in libscout.cpp */
44
extern ros::NodeHandle libscout_node;
44
extern ros::NodeHandle node;
45 45

  
46 46
/** ROS publisher and client declaration */
47 47
ros::Publisher button_event_publisher;
......
55 55
 */
56 56
void libbuttons_init()
57 57
{
58
  button_event_publisher = libscout_node.advertise<buttons::button_event>("libbuttons", 10);
59
  query_buttons_client = libscout_node.serviceClient<buttons::query_buttons>("libbuttons");
58
  button_event_publisher = node.advertise<buttons::button_event>("libbuttons", 10);
59
  query_buttons_client = node.serviceClient<buttons::query_buttons>("libbuttons");
60 60
}
61 61

  
62 62
/*!
scout/libscout/src/libheadlights.cpp
38 38
#include "libheadlights.h"
39 39

  
40 40
/* ROS node created in libscout.cpp */
41
extern ros::NodeHandle libscout_node;
41
extern ros::NodeHandle node;
42 42

  
43 43
/** ROS publisher and client declaration */
44 44
ros::Publisher set_headlights_publisher;
......
51 51
void libheadlights_init()
52 52
{
53 53
  set_headlights_publisher =
54
		libscout_node.advertise<headlights::set_headlights>("libheadlights", 10);
54
		node.advertise<headlights::set_headlights>("libheadlights", 10);
55 55
}
56 56

  
57 57
/*!
scout/libscout/src/libmotors.cpp
37 37
#include "libmotors.h"
38 38

  
39 39
/* ROS node created in libscout.cpp */
40
extern ros::NodeHandle libscout_node;
40
extern ros::NodeHandle node;
41 41

  
42 42
/** ROS publisher and client declaration */
43 43
ros::Publisher set_motors_publisher;
44 44
ros::ServiceClient query_motors_client;
45 45

  
46
/*!
47
 * \brief Initialize the motors module of libscout.
46
/**
47
 * @brief Initialize the motors module of libscout.
48 48
 *
49 49
 * Initialize the libscout node as a publisher of set_motors and a client of
50 50
 * query_motors.
51 51
 */
52 52
void libmotors_init()
53 53
{
54
  set_motors_publisher = libscout_node.advertise<motors::set_motors>("libmotors", 10);
55
  query_motors_client = libscout_node.serviceClient<motors::query_motors>("libmotors");
54
    set_motors_publisher =
55
        node.advertise<motors::set_motors>("set_motors", QUEUE_SIZE);
56
    query_motors_client =
57
        node.serviceClient<motors::query_motors>("query_motors");
56 58
}
57 59

  
58
/*!
59
 * \brief Set motor speeds
60
/**
61
 * @brief Sets all the speeds according to the specificiation of which motors
62
 *        to set.
63
 *
64
 * @param which A bitmask of which motors need to be set.
65
 * @param speed The value to set the motors to.
66
 * @param units The units the speed is expressed in.
67
 * @return Function status
68
 */
69
int motors_set(int which, float speed, char units)
70
{
71
    float speed_fl, speed_fr, speed_bl, speed_br;
72
    speed_fl = speed_fr = speed_bl = speed_br = speed;
73

  
74
    if(which & MOTOR_FL_REV)
75
    {
76
        speed_fl = -speed;
77
    }
78
    if(which & MOTOR_FR_REV)
79
    {
80
        speed_fr = -speed;
81
    }
82
    if(which & MOTOR_BL_REV)
83
    {
84
        speed_bl = -speed;
85
    }
86
    if(which & MOTOR_BR_REV)
87
    {
88
        speed_br = -speed;
89
    }
90

  
91
    return motors_set_each(which, speed_fl, speed_fr, speed_bl, speed_br,
92
                           units);
93
}
94

  
95
/**
96
 * @brief Sets the left and right sides of scout to different speeds.
97
 *
98
 * @param speed_l The speed of both left motors.
99
 * @param speed_r The speed of both right motors.
100
 * @param units The units to set to.
101
 * @return Function status
102
 */
103
int motors_set_sides(float speed_l, float speed_r, char units)
104
{
105
    return motors_set_each(MOTOR_ALL, speed_l, speed_r, speed_l, speed_r,
106
                               units);
107
}
108

  
109
/**
110
 * @brief Set motor speeds
60 111
 * Sets the speeds of the motors as a percentage of top speed. Can selectively
61 112
 * select which motors to set, and which to remain at previous speed.
62
 * \param speed The speed the motors should be set to
63
 * \param which A bitmask of which motors should be set
64
 * \return Function status
113
 *
114
 * @param which A bitmask of which motors should be set.
115
 * @param speed The speed the motors should be set to.
116
 * @param units Optional units for the speeds.
117
 * @return Function status
65 118
 */
66
int motors_set(int speed, int which, char units=MOTOR_PERCENT)
119
int motors_set_each(int which,
120
                    float speed_fl, float speed_fr,
121
                    float speed_bl, float speed_br,
122
                    char units)
67 123
{
68
  /** \todo Set fields of the message based on params */
69
  
70
	motors::set_motors msg;
71
	
72
  if(!ros::ok())
73
	{
74
    return LIB_ERROR;
75
  }
76
 
77
  /* Set the speed for each motor according to the which bitmask*/
78
  
79
  if(which & MOTOR_FL_REV)
80
	{
81
    msg.fl_speed = -1 * speed;
82
  }
83
  if(which & MOTOR_FR_REV)
84
	{
85
    msg.fr_speed = -1 * speed;
86
  }
87
  if(which & MOTOR_BL_REV)
88
	{
89
    msg.bl_speed = -1 * speed;
90
  }
91
  if(which & MOTOR_BR_REV)
92
	{
93
    msg.br_speed = -1 * speed;
94
  }if(which & MOTOR_FL)
95
	{
96
    msg.fl_speed = speed;
97
  }
98
  if(which & MOTOR_FR)
99
	{
100
    msg.fr_speed = speed;
101
  }
102
  if(which & MOTOR_BL)
103
	{
104
    msg.bl_speed = speed;
105
  }
106
  if(which & MOTOR_BR)
107
	{
108
    msg.br_speed = speed;
109
  }
110

  
111
  /* Specify which units the speeds are given in */
112
  msg.units = units;
113

  
114
  /* Publishes message to set_motors topic */
115
  set_motors_publisher.publish(msg);
116
  ros::spinOnce();
117

  
118
  return LIB_OK;
124
    check_which_ok(which);
125

  
126
    motors::set_motors msg;
127

  
128
    if(!ros::ok())
129
    {
130
        return LIB_ERROR;
131
    }
132

  
133
    /* Set all the speeds (the booleans in the set_motors message determine
134
     * which ones will be used) */
135
    msg.fl_speed = speed_fl;
136
    msg.fr_speed = speed_fr;
137
    msg.bl_speed = speed_bl;
138
    msg.br_speed = speed_br;
139

  
140
    /* Tell the motors node which motors need to be updated */
141
    msg.fl_set = msg.fr_set = msg.bl_set = msg.br_set = false;
142
    if(which & (MOTOR_FL | MOTOR_FL_REV))
143
    {
144
        msg.fl_set = true;
145
    }
146
    if(which & (MOTOR_FR | MOTOR_FR_REV))
147
    {
148
        msg.fr_set = true;
149
    }
150
    if(which & (MOTOR_BL | MOTOR_BL_REV))
151
    {
152
        msg.bl_set = true;
153
    }
154
    if(which & (MOTOR_BR | MOTOR_BR_REV))
155
    {
156
        msg.br_set = true;
157
    }
158

  
159
    /* Specify which units the speeds are given in */
160
    msg.units = units;
161

  
162
    /* Publishes message to set_motors topic */
163
    set_motors_publisher.publish(msg);
164
    ros::spinOnce();
165

  
166
    return LIB_OK;
119 167
}
120 168

  
121
/*!
122
 * \brief Query the current speeds of the motors
169
/**
170
 * Double-checks the which variable to make sure the front and back
171
 * bits are not both set for a single motor.
172
 *
173
 * @param which The which motor specfication to check.
174
 */
175
void check_which_ok(int which)
176
{
177
    ROS_WARN_COND( ((which & MOTOR_FL) && (which & MOTOR_FL_REV)),
178
        "FL Motor set in both directions!");
179
    ROS_WARN_COND( ((which & MOTOR_FR) && (which & MOTOR_FR_REV)),
180
        "FR Motor set in both directions!");
181
    ROS_WARN_COND( ((which & MOTOR_BL) && (which & MOTOR_BL_REV)),
182
        "BL Motor set in both directions!");
183
    ROS_WARN_COND( ((which & MOTOR_BR) && (which & MOTOR_BR_REV)),
184
        "BR Motor set in both directions!");
185
}
186

  
187
/**
188
 * @brief Query the current speeds of the motors
123 189
 *
124 190
 * Sends a request to the query_motors service which will reply with the
125 191
 *  current speed of each motor.
126 192
 *
127
 * \param which A bitmask that will specify which motor speed should be
193
 * @todo Change so we can get multiple motor speeds with one call
194
 *
195
 * @param which A bitmask that will specify which motor speed should be
128 196
 *  returned
129
 * \return The speed of the selected motor, or LIB_ERR if no motor selected
197
 * @return The speed of the selected motor, or LIB_ERR if no motor selected
130 198
 */
131

  
132
int motors_query(int which)
199
float motors_query(int which)
133 200
{
134
  motors::query_motors srv;
135
  if(query_motors_client.call(srv))
136
	{
137
    switch(which)
138
		{
139
      case MOTOR_FL:
140
        return srv.response.fl_speed;
141
      case MOTOR_FR:
142
        return srv.response.fr_speed;
143
      case MOTOR_BL:
144
        return srv.response.bl_speed;
145
      case MOTOR_BR:
146
        return srv.response.br_speed;
147
      default:
148
        ROS_WARN("Bad WHICH in motors_query.");
201
    motors::query_motors srv;
202
    if(query_motors_client.call(srv))
203
    {
204
        switch(which)
205
        {
206
            case MOTOR_FL:
207
                return srv.response.fl_speed;
208
            case MOTOR_FR:
209
                return srv.response.fr_speed;
210
            case MOTOR_BL:
211
                return srv.response.bl_speed;
212
            case MOTOR_BR:
213
                return srv.response.br_speed;
214
            default:
215
                ROS_WARN("Bad WHICH in motors_query.");
216
                return LIB_ERROR;
217
        }
218
    }
219
    else
220
    {
221
        ROS_ERROR("Failed to call service query_motors");
149 222
        return LIB_ERROR;
150 223
    }
151
  }
152
	else
153
	{
154
    ROS_ERROR("Failed to call service query_motors");
155
    return LIB_ERROR;
156
  }
157

  
158
  return 0;
224

  
225
    return 0;
159 226
}
scout/libscout/src/libmotors.h
62 62
#define MOTOR_RIGHT_REV MOTOR_FR_REV | MOTOR_BR_REV
63 63
#define MOTOR_LEFT_SPIN MOTOR_LEFT_REV | MOTOR_RIGHT
64 64
#define MOTOR_RIGHT_SPIN MOTOR_LEFT | MOTOR_RIGHT_REV
65

  
65 66
#define MOTOR_PERCENT 'p'
66 67
#define MOTOR_MMS 'm'
67 68
#define MOTOR_CMS 'c'
68 69
#define MOTOR_ABSOLUTE 'a'
70
#define MOTOR_DEFAULT_UNIT MOTOR_PERCENT
69 71

  
70 72
void libmotors_init();
71
int motors_set(int speed, int which);
72
int motors_query(int which);
73
int motors_set(int which, float speed, char units=MOTOR_DEFAULT_UNIT);
74
int motors_set_sides(float speed_l, float speed_r,
75
                     char units=MOTOR_DEFAULT_UNIT);
76
int motors_set_each(int which,
77
                    float speed_fl, float speed_fr,
78
                    float speed_bl, float speed_br,
79
                    char units=MOTOR_DEFAULT_UNIT);
80
void check_which_ok(int which);
81
float motors_query(int which);
73 82

  
74 83
#endif
75 84

  
scout/libscout/src/libscout.cpp
38 38
#include "libscout.h"
39 39

  
40 40
/* Global objects */
41
ros::NodeHandle libscout_node;
41
ros::NodeHandle node;
42 42

  
43 43
/** \todo Decide how to call user behaviors
44 44
  * I'm thinking that there be a function call in main that calls the "main"
scout/libscout/src/tags
15 15
_LIBSCOUT_H_	libscout.h	41
16 16
init	libscout.cpp	/^int init(int modules){$/
17 17
libmotors_init	libmotors.cpp	/^void libmotors_init(){$/
18
libscout_node	constants.h	58
18
node	constants.h	58
19 19
motors_query	libmotors.cpp	/^int motors_query(char which){$/
20 20
motors_set	libmotors.cpp	/^void motors_set(int speed, char which){$/
21 21
motors_speed_set	libmotors.cpp	/^void motors_speed_set(int speed, char which){$/
scout/motors/manifest.xml
3 3
     motors
4 4
     Module to drive the motors and provide all motor control functionality.
5 5
  </description>
6
  <author>Ben</author>
6
  <author>Ben Wasserman</author>
7 7
  <license>BSD</license>
8 8
  <review status="unreviewed" notes=""/>
9 9
  <url>https://www.roboticsclub.org/redmine/projects/colonyscout/wiki</url>
10 10
  <depend package="roscpp"/>
11 11
  <depend package="std_msgs"/>
12 12

  
13
  <export>
14
    <cpp cflags="-I${prefix}/include" lflags="-Wl,-rpath,${prefix}/lib -L${prefix}/lib -lmotors"/>
15
  </export>
16

  
13 17
</package>
14 18

  
15 19

  
scout/motors/msg/set_motors.msg
1 1
Header header
2
int8 fl_speed
3
int8 fr_speed
4
int8 bl_speed
5
int8 br_speed
2

  
3
# Keeps track of which motors need to be changed
6 4
int8 which
5

  
6
# Set these to true if the motor should be updated
7
bool fl_set
8
bool fr_set
9
bool bl_set
10
bool br_set
11

  
12
# The motor speeds, from -255 to 255 if absolute
13
# -100 to 100 if percentage
14
# Decimal values if in measured units
15
float32 fl_speed
16
float32 fr_speed
17
float32 bl_speed
18
float32 br_speed
19

  
20
# Allows motor speeds to be specified mm/s, cm/s, percent, or absolute
7 21
int8 units
scout/motors/src/motors.cpp
34 34
 **/
35 35

  
36 36
#include "ros/ros.h"
37
#include "motors_util.cpp"
37 38
#include "motors.h"
38 39
//#include "libscout/src/constants.h"
39 40
#include <cstdlib>
......
45 46
 * @{
46 47
 **/
47 48

  
49

  
50

  
48 51
/* Motor state variables
49 52
 * Speeds expressed as absolute speed out of max speed (0 - +-MAXSPEED)
50 53
 * Absolute speed is the speed written to the hardware to move the motors
51 54
 */
52
/** @todo Fix types: static */
53
int motor_fl_speed; /**< The current speed of the front left motor. */
54
int motor_fr_speed; /**< The current speed of the front right motor. */
55
int motor_bl_speed; /**< The current speed of the back left motor. */
56
int motor_br_speed; /**< The current speed of the back right motor. */
55
static int motor_fl_speed; /**< The current speed of the front left motor. */
56
static int motor_fr_speed; /**< The current speed of the front right motor. */
57
static int motor_bl_speed; /**< The current speed of the back left motor. */
58
static int motor_br_speed; /**< The current speed of the back right motor. */
57 59

  
58 60
/**
59 61
 * @brief Sets motor speed
......
65 67
 */
66 68
void motors_set(const motors::set_motors::ConstPtr& msg)
67 69
{
68
    /** @todo Edit to only set requested motors, not all */
69
    int which = msg->which;
70
    if(which & MOTOR_FL_REV)
71
    {
72
      motor_fl_speed = -1 * motors_rel_to_abs(msg->fl_speed, msg->units);
73
    }
74
    if(which & MOTOR_FR_REV)
75
    {
76
      motor_fr_speed = -1 * motors_rel_to_abs(msg->fr_speed, msg->units);
77
    }
78
    if(which & MOTOR_BL_REV)
79
    {
80
      motor_bl_speed = -1 * motors_rel_to_abs(msg->bl_speed, msg->units);
81
    }
82
    if(which & MOTOR_BR_REV)
83
    {
84
      motor_br_speed = -1 * motors_rel_to_abs(msg->br_speed, msg->units);
85
    }
86
    if(which & MOTOR_FL)
70
    if(msg->fl_set)
87 71
    {
88 72
      motor_fl_speed = motors_rel_to_abs(msg->fl_speed, msg->units);
89 73
    }
90
    if(which & MOTOR_FR)
74
    if(msg->fr_set)
91 75
    {
92 76
      motor_fr_speed = motors_rel_to_abs(msg->fr_speed, msg->units);
93 77
    }
94
    if(which & MOTOR_BL)
78
    if(msg->bl_set)
95 79
    {
96 80
      motor_bl_speed = motors_rel_to_abs(msg->bl_speed, msg->units);
97 81
    }
98
    if(which & MOTOR_BR)
82
    if(msg->br_set)
99 83
    {
100 84
      motor_br_speed = motors_rel_to_abs(msg->br_speed, msg->units);
101 85
    }
102 86

  
103
    /* Write speeds to hardware */
104 87
    /** @todo Add code to write speeds to hardware */
88
    ROS_DEBUG("Motor speeds set");
105 89
}
106 90

  
107 91
/**
......
126 110
}
127 111

  
128 112
/**
129
 * @brief Converts set speeds (of various units) to absolute speeds.
130
 *
131
 * @param speed The speed expressed in the desired units
132
 * @param units The units the desired speed is measured in
133
 * @return The absolute speed of the motor
134
 **/
135
int motors_rel_to_abs(int rel_speed, int units)
136
{
137
    switch(units)
138
    {
139
      case MOTOR_ABSOLUTE:/* Speed given as absolute */
140
        return rel_speed;
141
      case MOTOR_PERCENT:/* Convert from percentage */
142
        return rel_speed * MAXSPEED / 100;
143
      case MOTOR_MMS:/* Convert from mm/s */
144
        /** @todo Make math to do this conversion **/
145
        return rel_speed;
146
      case MOTOR_CMS:/* Convert from cm/s */
147
        /** @todo Make math to do this conversion **/
148
        return rel_speed;
149
      default: /* The units aren't recognized */
150
        /** @todo Decide on default case. Either percent or absolute. **/
151
        return rel_speed;
152
    }
153
}
154

  
155
/**
156
 * @brief Convert absolute speeds to speeds of various units.
157
 *
158
 * @param speed The speed expressed in absolute units.
159
 * @param units The units the desired speed is measured in.
160
 * @return The relative speed of the motor in desired units.
161
 **/
162
int motors_abs_to_rel(int abs_speed, int units)
163
{
164
    switch(units)
165
    {
166
      case MOTOR_ABSOLUTE:/* Speed given as absolute */
167
        return abs_speed;
168
      case MOTOR_PERCENT:/* Convert from percentage */
169
        return abs_speed * 100 / MAXSPEED;
170
      case MOTOR_MMS:/* Convert from mm/s */
171
        /** @todo Make math to do this conversion **/
172
        return abs_speed;
173
      case MOTOR_CMS:/* Convert from cm/s */
174
        /** @todo Make math to do this conversion **/
175
        return abs_speed;
176
      default: /* The units aren't recognized */
177
        /** @todo Decide on default case. Either percent or absolute. **/
178
        return abs_speed;
179
    }
180
}
181

  
182
/**
183 113
 * @brief Motors driver. This is a ROS node that controls motor speeds.
184 114
 *
185 115
 * This is the main function for the motors node. It is run when the node
......
196 126
    ros::init(argc, argv, "motors_driver");
197 127

  
198 128
    /* Advertise that this serves the query_motors service */
199
    ros::NodeHandle n;
200
    ros::ServiceServer service = n.advertiseService("query_motors",
201
                                                    motors_query);
129
    ros::NodeHandle node;
130
    ros::ServiceServer service = node.advertiseService("query_motors",
131
                                                       motors_query);
202 132

  
203 133
    /* Subscribe to the set_motors topic */
204
    ros::Subscriber sub0 = n.subscribe("set_motors", QUEUE_SIZE, motors_set);
134
    ros::Subscriber sub0 = node.subscribe("set_motors", QUEUE_SIZE, motors_set);
205 135

  
206 136
    /* Initialize hardware for motors */
207 137
    // Hardware init functions here
scout/motors/src/motors.h
40 40
#include "motors/query_motors.h"
41 41
#include "motors/set_motors.h"
42 42

  
43
#define MAXSPEED 512
44
#define MOTOR_ALL 0xF
45
#define MOTOR_ALL_REV 0xF0
46
#define MOTOR_NONE 0x0
47
#define MOTOR_FL 0x8
48
#define MOTOR_FR 0x4
49
#define MOTOR_BL 0x2
50
#define MOTOR_BR 0x1
51
#define MOTOR_FL_REV 0x80
52
#define MOTOR_FR_REV 0x40
53
#define MOTOR_BL_REV 0x20
54
#define MOTOR_BR_REV 0x10
55
#define MOTOR_FRONT MOTOR_FL | MOTOR_FR
56
#define MOTOR_BACK MOTOR_BR | MOTOR_BR
57
#define MOTOR_LEFT MOTOR_FL | MOTOR_BL
58
#define MOTOR_RIGHT MOTOR_FR | MOTOR_BR
59
#define MOTOR_LEFT_REV MOTOR_FL_REV | MOTOR_BL_REV
60
#define MOTOR_RIGHT_REV MOTOR_FR_REV | MOTOR_BR_REV
61
#define MOTOR_LEFT_SPIN MOTOR_LEFT_REV | MOTOR_RIGHT
62
#define MOTOR_RIGHT_SPIN MOTOR_LEFT | MOTOR_RIGHT_REV
43
#define MAXSPEED 255
63 44
#define MOTOR_PERCENT 'p'
64 45
#define MOTOR_MMS 'm'
65 46
#define MOTOR_CMS 'c'

Also available in: Unified diff