Project

General

Profile

Statistics
| Branch: | Revision:

root / scout / scoutsim / src / sim_frame.cpp @ dec96050

History | View | Annotate | Download (6.64 KB)

1
/*
2
 * This package was developed by the CMU Robotics Club project using code
3
 * from Willow Garage, Inc.  Please see licensing.txt for details.
4
 *
5
 * All rights reserved.
6
 *
7
 * @brief Keeps track of the frame (visualization of the whole environment).
8
 * @file sim_frame.cpp
9
 * @author Colony Project, CMU Robotics Club
10
 * @author Alex Zirbel
11
 */
12

    
13
#include "scoutsim/sim_frame.h"
14

    
15
#include <ros/package.h>
16
#include <cstdlib>
17
#include <ctime>
18

    
19
#define DEFAULT_BG_R 0x45
20
#define DEFAULT_BG_G 0x56
21
#define DEFAULT_BG_B 0xff
22

    
23
namespace scoutsim
24
{
25

    
26
    SimFrame::SimFrame(wxWindow* parent)
27
        : wxFrame(parent, wxID_ANY, wxT("ScoutSim"), wxDefaultPosition,
28
                  wxSize(500, 500), wxDEFAULT_FRAME_STYLE & ~wxRESIZE_BORDER)
29
          , frame_count_(0)
30
          , id_counter_(0)
31
    {
32
        srand(time(NULL));
33

    
34
        update_timer_ = new wxTimer(this);
35
        update_timer_->Start(16);
36

    
37
        Connect(update_timer_->GetId(), wxEVT_TIMER,
38
                wxTimerEventHandler(SimFrame::onUpdate), NULL, this);
39
        Connect(wxEVT_PAINT, wxPaintEventHandler(SimFrame::onPaint),
40
                NULL, this);
41

    
42
        nh_.setParam("background_r", DEFAULT_BG_R);
43
        nh_.setParam("background_g", DEFAULT_BG_G);
44
        nh_.setParam("background_b", DEFAULT_BG_B);
45

    
46
        std::string scouts[SCOUTSIM_NUM_SCOUTS] = 
47
        {
48
            "scout.png"
49
            "scout_forreal.png"
50
        };
51

    
52
        std::string images_path = ros::package::getPath("scoutsim")+"/images/";
53
        for (size_t i = 0; i < SCOUTSIM_NUM_SCOUTS; ++i)
54
        {
55
            scout_images_[i].LoadFile(
56
                wxString::FromAscii((images_path + scouts[i]).c_str()));
57
            scout_images_[i].SetMask(true);
58
            scout_images_[i].SetMaskColour(255, 255, 255);
59
        }
60

    
61
        meter_ = scout_images_[0].GetHeight();
62

    
63
        path_bitmap_ = wxBitmap(GetSize().GetWidth(), GetSize().GetHeight());
64
        path_dc_.SelectObject(path_bitmap_);
65
        clear();
66

    
67
        clear_srv_ = nh_.advertiseService("clear",
68
                                          &SimFrame::clearCallback, this);
69
        reset_srv_ = nh_.advertiseService("reset",
70
                                          &SimFrame::resetCallback, this);
71
        spawn_srv_ = nh_.advertiseService("spawn",
72
                                          &SimFrame::spawnCallback, this);
73
        kill_srv_ = nh_.advertiseService("kill",
74
                                         &SimFrame::killCallback, this);
75

    
76
        ROS_INFO("Starting scoutsim with node name %s",
77
                 ros::this_node::getName().c_str()) ;
78

    
79
        width_in_meters_ = GetSize().GetWidth() / meter_;
80
        height_in_meters_ = GetSize().GetHeight() / meter_;
81
        spawnScout("", width_in_meters_ / 2.0, height_in_meters_ / 2.0, 0);
82
    }
83

    
84
    SimFrame::~SimFrame()
85
    {
86
        delete update_timer_;
87
    }
88

    
89
    bool SimFrame::spawnCallback(scoutsim::Spawn::Request& req,
90
                                 scoutsim::Spawn::Response& res)
91
    {
92
        std::string name = spawnScout(req.name, req.x, req.y, req.theta);
93
        if (name.empty())
94
        {
95
            ROS_ERROR("A scout named [%s] already exists", req.name.c_str());
96
            return false;
97
        }
98

    
99
        res.name = name;
100

    
101
        return true;
102
    }
103

    
104
    bool SimFrame::killCallback(scoutsim::Kill::Request& req,
105
                                scoutsim::Kill::Response&)
106
    {
107
        M_Scout::iterator it = scouts_.find(req.name);
108
        if (it == scouts_.end())
109
        {
110
            ROS_ERROR("Tried to kill scout [%s], which does not exist",
111
                      req.name.c_str());
112
            return false;
113
        }
114

    
115
        scouts_.erase(it);
116

    
117
        return true;
118
    }
119

    
120
    bool SimFrame::hasScout(const std::string& name)
121
    {
122
        return scouts_.find(name) != scouts_.end();
123
    }
124

    
125
    std::string SimFrame::spawnScout(const std::string& name, float x,
126
                                       float y, float angle)
127
    {
128
        std::string real_name = name;
129
        if (real_name.empty())
130
        {
131
            do
132
            {
133
                std::stringstream ss;
134
                ss << "scout" << ++id_counter_;
135
                real_name = ss.str();
136
            } while (hasScout(real_name));
137
        }
138
        else
139
        {
140
            if (hasScout(real_name))
141
            {
142
                return "";
143
            }
144
        }
145

    
146
        ScoutPtr t(new Scout(ros::NodeHandle(real_name),
147
                   scout_images_[rand() % SCOUTSIM_NUM_SCOUTS],
148
                   Vector2(x, y), angle));
149
        scouts_[real_name] = t;
150

    
151
        ROS_INFO("Spawning scout [%s] at x=[%f], y=[%f], theta=[%f]",
152
                 real_name.c_str(), x, y, angle);
153

    
154
        return real_name;
155
    }
156

    
157
    void SimFrame::clear()
158
    {
159
        int r = DEFAULT_BG_R;
160
        int g = DEFAULT_BG_G;
161
        int b = DEFAULT_BG_B;
162

    
163
        nh_.param("background_r", r, r);
164
        nh_.param("background_g", g, g);
165
        nh_.param("background_b", b, b);
166

    
167
        path_dc_.SetBackground(wxBrush(wxColour(r, g, b)));
168
        path_dc_.Clear();
169
    }
170

    
171
    void SimFrame::onUpdate(wxTimerEvent& evt)
172
    {
173
        ros::spinOnce();
174

    
175
        updateScouts();
176

    
177
        if (!ros::ok())
178
        {
179
            Close();
180
        }
181
    }
182

    
183
    void SimFrame::onPaint(wxPaintEvent& evt)
184
    {
185
        wxPaintDC dc(this);
186

    
187
        dc.DrawBitmap(path_bitmap_, 0, 0, true);
188

    
189
        M_Scout::iterator it = scouts_.begin();
190
        M_Scout::iterator end = scouts_.end();
191
        for (; it != end; ++it)
192
        {
193
            it->second->paint(dc);
194
        }
195
    }
196

    
197
    void SimFrame::updateScouts()
198
    {
199
        if (last_scout_update_.isZero())
200
        {
201
            last_scout_update_ = ros::WallTime::now();
202
            return;
203
        }
204

    
205
        if (frame_count_ % 3 == 0)
206
        {
207
            path_image_ = path_bitmap_.ConvertToImage();
208
            Refresh();
209
        }
210

    
211
        M_Scout::iterator it = scouts_.begin();
212
        M_Scout::iterator end = scouts_.end();
213
        for (; it != end; ++it)
214
        {
215
            it->second->update(0.016, path_dc_, path_image_,
216
                               path_dc_.GetBackground().GetColour(),
217
                               width_in_meters_, height_in_meters_);
218
        }
219

    
220
        ++frame_count_;
221
    }
222

    
223

    
224
    bool SimFrame::clearCallback(std_srvs::Empty::Request&,
225
                                 std_srvs::Empty::Response&)
226
    {
227
        ROS_INFO("Clearing scoutsim.");
228
        clear();
229
        return true;
230
    }
231

    
232
    bool SimFrame::resetCallback(std_srvs::Empty::Request&,
233
                                 std_srvs::Empty::Response&)
234
    {
235
        ROS_INFO("Resetting scoutsim.");
236
        scouts_.clear();
237
        id_counter_ = 0;
238
        spawnScout("", width_in_meters_ / 2.0, height_in_meters_ / 2.0, 0);
239
        clear();
240
        return true;
241
    }
242

    
243
}