Project

General

Profile

Statistics
| Branch: | Revision:

root / scout / libscout / src / SonarControl.cpp @ 754da79f

History | View | Annotate | Download (6.07 KB)

1
/**
2
 * Copyright (c) 2011 Colony Project
3
 * 
4
 * Permission is hereby granted, free of charge, to any person
5
 * obtaining a copy of this software and associated documentation
6
 * files (the "Software"), to deal in the Software without
7
 * restriction, including without limitation the rights to use,
8
 * copy, modify, merge, publish, distribute, sublicense, and/or sell
9
 * copies of the Software, and to permit persons to whom the
10
 * Software is furnished to do so, subject to the following
11
 * conditions:
12
 * 
13
 * The above copyright notice and this permission notice shall be
14
 * included in all copies or substantial portions of the Software.
15
 * 
16
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
18
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
20
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23
 * OTHER DEALINGS IN THE SOFTWARE.
24
 */
25

    
26
/**
27
 * @file SonarControl.cpp
28
 * @brief Contains sonar function implementation
29
 * 
30
 * Contains functions for the use of sonar control.
31
 *
32
 * @author Colony Project, CMU Robotics Club
33
 * @author Priyanka Deo
34
 * @author Alex Zirbel
35
 **/
36

    
37
#include "SonarControl.h"
38

    
39
#define MAX_ATTEMPTS 10
40

    
41
using namespace std;
42

    
43
/**
44
 * @brief Initialize the sonar module of libscout.
45
 *
46
 * Initialize the libscout node as a publisher of sonar_set_scan and 
47
 * sonar_toggle and a client of query_sonar.
48
 */
49
SonarControl::SonarControl(const ros::NodeHandle& libscout_node,
50
                           string scoutname)
51
    : node(libscout_node)
52
{
53
    sonar_set_scan_client =
54
        node.serviceClient<sonar::sonar_set_scan>(scoutname+"/set_sonar_scan");
55
    sonar_toggle_client = 
56
        node.serviceClient<sonar::sonar_toggle>(scoutname + "/toggle_sonar");
57
    sonar_distance_sub = node.subscribe(scoutname + "/sonar_distance",
58
                                        QUEUE_SIZE,
59
                                        &SonarControl::distance_callback,
60
                                        this);
61

    
62
    // Initialize all the sonar readings to 0 and timestamps to undefined
63
    for (int i = 0; i < 48; i++)
64
    {
65
        readings[i] = 0;
66
        timestamps[i] = ros::Time::now(); // A common shortcut for no reading
67
    }
68

    
69
    /// @todo Test, and replace 10 with a const int
70
    num_attempts = MAX_ATTEMPTS;
71
}
72

    
73
/**
74
 * Update the array of sonar values, and the last read timestamps,
75
 * to reflect the new reading received.
76
 */
77
void SonarControl::distance_callback(const sonar::sonar_distance::ConstPtr& msg)
78
{
79
    // Error checking so that the array doesn't cause a segfault
80
    if (msg->pos < 0 || msg-> pos > 23)
81
    {
82
        ROS_ERROR("SonarControl received an invalid sonar position.");
83
        return;
84
    }
85

    
86
    readings[msg->pos] = msg->distance0;
87
    readings[msg->pos + 24] = msg->distance1;
88
    timestamps[msg->pos] = msg->header.stamp;
89
    timestamps[msg->pos + 24] = msg->header.stamp;
90
}
91

    
92
/**
93
 * @brief Sets the sonar to a position.
94
 *
95
 * @param position Value between 0-180 of degree position to set sonar
96
 */
97
void SonarControl::set_single(int position)
98
{
99
    set_range(position, position);
100
}
101

    
102
/**
103
 * @brief Sets the sonar to scan between two positions
104
 *
105
 * @param start_pos The leftmost (smallest) value that the sonar can take
106
 * @param end_pos The rightmost (largest) value that the sonar can take
107
 */
108
void SonarControl::set_range(int start_pos, int end_pos)
109
{
110
    // Check that the range is valid
111
    if (start_pos < 0 || end_pos < 0 || start_pos > 23 || end_pos > 23)
112
    {
113
        ROS_ERROR("Commanded SonarControl::set_range to a bad value.");
114
        return;
115
    }
116

    
117
    // Sort the start and end positions into increasing order
118
    if (start_pos > end_pos)
119
    {
120
        int temp = start_pos;
121
        start_pos = end_pos;
122
        end_pos = temp;
123
    }
124

    
125
    // Make sure sonar is on
126
    set_on();
127

    
128
    // Set scan range
129
    sonar::sonar_set_scan srv;
130
    srv.request.stop_l = start_pos;
131
    srv.request.stop_r = end_pos;
132

    
133
    // Check if the service call failed or if the response was false
134
    if (!sonar_set_scan_client.call(srv) || srv.response.ack == false)
135
    {
136
        if (--num_attempts == 0)
137
        {
138
            ROS_ERROR("SonarControl::set_range() failed permanently.");
139
        }
140

    
141
        ROS_WARN("SonarControl::set_range() failed once.");
142
    }
143
}
144

    
145
/**
146
 * @brief Turn on sonar readings
147
 *
148
 * (Re)starts sonar panning and taking readings.
149
 */
150
void SonarControl::set_on()
151
{
152
    set_power(true);
153
}
154

    
155
/**
156
 * @brief Turn off sonar readings
157
 *
158
 * Stops sonar from panning and taking readings.
159
 */
160
void SonarControl::set_off()
161
{
162
    set_power(false);
163
}
164

    
165
/**
166
 * @brief Turn sonar readings either off or on.
167
 *
168
 * Attempts to turn the readings off or on, num_attempts times.
169
 *
170
 * @param is_on True if power should be set on, false if should be off.
171
 */
172
void SonarControl::set_power(bool is_on)
173
{
174
    sonar::sonar_toggle srv;
175
    srv.request.set_on = is_on;
176

    
177
    // Check if the service call failed or if the response was false
178
    if (!sonar_toggle_client.call(srv) || srv.response.ack == false)
179
    {
180
        if (--num_attempts == 0)
181
        {
182
            ROS_ERROR("SonarControl::set_power() failed permanently.");
183
        }
184

    
185
        ROS_WARN("SonarControl::set_power() failed once.");
186
    }
187

    
188
    // Reset num_attempts
189
    num_attempts = MAX_ATTEMPTS;
190
}
191

    
192
int* SonarControl::get_sonar_readings()
193
{
194
  return readings;
195
}
196

    
197
/**
198
 * @brief Converts value returne by sonar to physical distances.
199
 *
200
 * @param sonar_value The returned value of the sonar
201
 * @return The physical distance measured by the sonar.
202
 **/
203
//float sonar_to_dist(float sonar_value)
204
//{
205
    //TODO impelement later based on sonar readings
206
//    return sonar_value;
207
//}
208

    
209
/**
210
 * @brief Converts values from physical distances to values read by sonar
211
 *
212
 * @param distance The physical distance as measured.
213
 * @return The value read by the sonar that corresponds to the given distance
214
 **/
215
//float dist_to_sonar(float distance)
216
//{
217
    //TODO implement later based on sonar readings
218
//    return distance;
219
//}