Project

General

Profile

Statistics
| Branch: | Revision:

robobuggy / buggyvis / src / buggy.cpp @ 066966cf

History | View | Annotate | Download (5.54 KB)

1
/*
2
 * Copyright (c) 2009, Willow Garage, Inc.
3
 * All rights reserved.
4
 *
5
 * Redistribution and use in source and binary forms, with or without
6
 * modification, are permitted provided that the following conditions are met:
7
 *
8
 *     * Redistributions of source code must retain the above copyright
9
 *       notice, this list of conditions and the following disclaimer.
10
 *     * Redistributions in binary form must reproduce the above copyright
11
 *       notice, this list of conditions and the following disclaimer in the
12
 *       documentation and/or other materials provided with the distribution.
13
 *     * Neither the name of the Willow Garage, Inc. nor the names of its
14
 *       contributors may be used to endorse or promote products derived from
15
 *       this software without specific prior written permission.
16
 *
17
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27
 * POSSIBILITY OF SUCH DAMAGE.
28
 */
29

    
30
#include "buggyvis/buggy.h"
31

    
32
#include <QColor>
33
#include <QRgb>
34

    
35
#define DEFAULT_PEN_R 0xb3
36
#define DEFAULT_PEN_G 0xb8
37
#define DEFAULT_PEN_B 0xff
38

    
39
namespace buggysim
40
{
41

    
42
  Turtle::Turtle(const ros::NodeHandle& nh,
43
                 const QImage& wall_image,
44
                 const QImage& turtle_image,
45
                 const QPointF& pos,
46
                 float orient)
47
    : nh_(nh)
48
    , turtle_image_(turtle_image)
49
    , wall_image_(wall_image)
50
    , pos_(pos)
51
    , orient_(orient)
52
      //, lin_vel_(2.0)
53
      //, ang_vel_(0.0)
54
      //, turnAngle_(0.0)
55
    , pen_on_(true)
56
    , pen_(QColor(DEFAULT_PEN_R, DEFAULT_PEN_G, DEFAULT_PEN_B))
57
  {
58
    pen_.setWidth(3);
59
    
60
    pose_sub_ = nh_.subscribe
61
      ("pose", 1, &Turtle::poseCallback, this);
62
    
63
    //Services
64
    set_pen_srv_ = nh_.advertiseService
65
      ("set_pen", &Turtle::setPenCallback, this);
66
    //teleport_relative_srv_ = nh_.advertiseService
67
    //  ("teleport_relative", &Turtle::teleportRelativeCallback, this);
68
    //teleport_absolute_srv_ = nh_.advertiseService
69
    //  ("teleport_absolute", &Turtle::teleportAbsoluteCallback, this);
70
    
71
    meter_ = turtle_image_.height();
72
    rotateImage();
73
  }
74
  
75
  void Turtle::poseCallback(const buggymsgs::PoseConstPtr& pcp)
76
  {
77
    last_command_time_ = ros::WallTime::now();
78
    pose_ = *pcp;
79
  }
80
  
81
  bool Turtle::setPenCallback(buggysim::SetPen::Request& req, 
82
                              buggysim::SetPen::Response&)
83
  {
84
    pen_on_ = !req.off;
85
    if (req.off)
86
      {
87
        return true;
88
      }
89

    
90
    QPen pen(QColor(req.r, req.g, req.b));
91
    if (req.width != 0)
92
      {
93
        pen.setWidth(req.width);
94
      }
95

    
96
    pen_ = pen;
97
    return true;
98
  }
99

    
100
  void Turtle::rotateImage()
101
  {
102
    QTransform transform;
103
    transform.rotate(-orient_ * 180.0 / PI + 90.0);
104
    turtle_rotated_image_ = turtle_image_.transformed(transform);
105
  }
106

    
107
  /**
108
   * TODO: convert this to take just an angle. And include drag. 
109
   *       and include acceleration/joule dump
110
   */
111
  bool Turtle::update(QPainter& path_painter, 
112
                      const QImage& path_image, 
113
                      qreal canvas_width, 
114
                      qreal canvas_height)
115
  {
116
    bool modified = false;
117
    qreal old_orient = orient_;
118

    
119
    teleport_requests_.clear();
120

    
121
    // Update my position
122
    QPointF old_pos = pos_;
123
    double dt = (ros::WallTime::now() - last_command_time_).toSec();
124

    
125
    //orient_ = std::fmod(orient_ - (turnAngle_ * dt), 2*PI);
126
    //if (orient_ < 0.0) {
127
    //  orient_ += 2*PI;
128
    //}
129
    // TODO: why add pi/2? is this just because they got the 
130
    //       sin/cos mixed up?
131
    //pos_.rx() += std::cos(orient_) * lin_vel_ * dt;
132
    //pos_.ry() -= std::sin(orient_) * lin_vel_ * dt;
133

    
134
    pos_.rx() = pose_.x;
135
    pos_.ry() = pose_.y;
136

    
137
    // Clamp to screen size
138
    // TODO: change to use another image, to detect walls. 
139
    if (pos_.x() < 0 || pos_.x() > canvas_width ||
140
        pos_.y() < 0 || pos_.y() > canvas_height)
141
      {
142
        ROS_WARN("Oh no! I hit the wall! (Clamping from [x=%f, y=%f])", pos_.x(), pos_.y());
143
      }
144

    
145
    pos_.setX(std::min(std::max(static_cast<double>(pos_.x()), 0.0), 
146
                       static_cast<double>(canvas_width)));
147
    pos_.setY(std::min(std::max(static_cast<double>(pos_.y()), 0.0), 
148
                       static_cast<double>(canvas_height)));
149

    
150
    /** END POSITION UPDATE */
151
    //buggymsgs::Pose p;
152
    //p.x = pos_.x();
153
    //p.y = canvas_height - pos_.y();
154
    //p.angle = orient_;
155
    //p.linear_velocity = lin_vel_;
156
    //pose_pub_.publish(p);
157

    
158
    ROS_DEBUG("[%s]: pos_x: %f pos_y: %f theta: %f", 
159
              nh_.getNamespace().c_str(), 
160
              pos_.x(), pos_.y(), orient_);
161

    
162
    if (orient_ != old_orient)
163
      {
164
        rotateImage();
165
        modified = true;
166
      }
167

    
168
    if (pos_ != old_pos)
169
      {
170
        if (pen_on_)
171
          {
172
            path_painter.setPen(pen_);
173
            path_painter.drawLine(pos_ * meter_, old_pos * meter_);
174
          }
175
        modified = true;
176
      }
177

    
178
    return modified;
179
  }
180

    
181
  void Turtle::paint(QPainter& painter)
182
  {
183
    QPointF p = pos_ * meter_;
184
    p.rx() -= 0.5 * turtle_rotated_image_.width();
185
    p.ry() -= 0.5 * turtle_rotated_image_.height();
186
    painter.drawImage(p, turtle_rotated_image_);
187
  }
188

    
189
}