[TeamTalk 32]: [569] TeamTalk: 1.
tk@edam.speech.cs.cmu.edu
tk at edam.speech.cs.cmu.edu
Thu Apr 5 12:56:50 EDT 2007
An HTML attachment was scrubbed...
URL: http://mailman.srv.cs.cmu.edu/pipermail/teamtalk-developers/attachments/20070405/e94c6f10/attachment-0001.html
-------------- next part --------------
Property changes on: TeamTalk
___________________________________________________________________
Name: svn:externals
+ Tools http://edam.speech.cs.cmu.edu/repos/olympus/Tools
Modified: TeamTalk/Agents/Agents.sln
===================================================================
--- TeamTalk/Agents/Agents.sln 2007-02-25 14:08:57 UTC (rev 568)
+++ TeamTalk/Agents/Agents.sln 2007-04-05 16:56:50 UTC (rev 569)
@@ -1,24 +1,6 @@
Microsoft Visual Studio Solution File, Format Version 9.00
# Visual Studio 2005
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Audio_Server", "MultiDecoder\Audio_Server\Audio_Server.vcproj", "{C31484B0-179B-432D-AE1E-75FB90591F23}"
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Helios3", "Helios3\Helios3.vcproj", "{93C8F5F8-6C43-4179-9B9F-A31AA6438513}"
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Kalliope", "Kalliope\Kalliope.vcproj", "{9CDBFBA5-F7EB-432F-A7CF-2E80322FE2ED}"
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "NlgServer2", "NlgServer2\NlgServer2.vcproj", "{AB3C8BF7-BF9D-4A80-A956-E969B9D8542D}"
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "phoenix2", "Phoenix2\phoenix2.vcproj", "{7022E28A-B15B-4A61-876A-5962C8EC1219}"
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PrimitiveComm", "PrimitiveComm\PrimitiveComm.vcproj", "{4051C912-8C55-442F-9AF8-3F3AE9859776}"
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ProcessMonitor", "ProcessMonitor\ProcessMonitor.vcproj", "{73E306B4-6227-4843-8A59-9B85C382790C}"
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RavenClaw", "RavenClaw\RavenClaw.vcproj", "{538B76FD-E289-4CF7-A7FF-1ACB429B4F63}"
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Sphinx_Engine", "MultiDecoder\Sphinx_Engine\Sphinx_Engine.vcproj", "{6A7673C4-08F4-4490-93A5-5F7211B406CF}"
-EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "backendstub", "TeamTalkBackend\backendstub\backendstub.vcproj", "{596C5D37-C409-4C46-BA28-B7F5EFB96851}"
ProjectSection(ProjectDependencies) = postProject
{4051C912-8C55-442F-9AF8-3F3AE9859776} = {4051C912-8C55-442F-9AF8-3F3AE9859776}
@@ -30,87 +12,15 @@
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TeamTalkDM", "TeamTalkDM\TeamTalkDM.vcproj", "{8AD2EDB1-F154-40E3-8317-6799592E8B34}"
- ProjectSection(ProjectDependencies) = postProject
- {538B76FD-E289-4CF7-A7FF-1ACB429B4F63} = {538B76FD-E289-4CF7-A7FF-1ACB429B4F63}
- EndProjectSection
EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PrimitiveComm", "PrimitiveComm\PrimitiveComm.vcproj", "{4051C912-8C55-442F-9AF8-3F3AE9859776}"
+EndProject
Global
- GlobalSection(SourceCodeControl) = preSolution
- SccNumberOfProjects = 8
- SccProjectUniqueName0 = MultiDecoder\\Audio_Server\\Audio_Server.vcproj
- SccProjectName0 = \u0022$/CommonAgents-2005/MultiDecoder/Audio_Server\u0022,\u0020ONACAAAA
- SccLocalPath0 = MultiDecoder\\Audio_Server
- SccProvider0 = MSSCCI:Microsoft\u0020Visual\u0020SourceSafe
- SccProjectUniqueName1 = Helios3\\Helios3.vcproj
- SccProjectName1 = \u0022$/CommonAgents-2005/Helios3\u0022,\u0020ZJACAAAA
- SccLocalPath1 = Helios3
- SccProvider1 = MSSCCI:Microsoft\u0020Visual\u0020SourceSafe
- SccProjectUniqueName2 = Kalliope\\Kalliope.vcproj
- SccProjectName2 = \u0022$/CommonAgents-2005/Kalliope\u0022,\u0020MLACAAAA
- SccLocalPath2 = Kalliope
- SccProvider2 = MSSCCI:Microsoft\u0020Visual\u0020SourceSafe
- SccProjectUniqueName3 = NlgServer2\\NlgServer2.vcproj
- SccProjectName3 = \u0022$/CommonAgents-2005/NlgServer2\u0022,\u0020JOACAAAA
- SccLocalPath3 = NlgServer2
- SccProvider3 = MSSCCI:Microsoft\u0020Visual\u0020SourceSafe
- SccProjectUniqueName4 = Phoenix2\\phoenix2.vcproj
- SccProjectName4 = \u0022$/CommonAgents-2005/Phoenix2\u0022,\u0020APACAAAA
- SccLocalPath4 = Phoenix2
- SccProvider4 = MSSCCI:Microsoft\u0020Visual\u0020SourceSafe
- SccProjectUniqueName5 = ProcessMonitor\\ProcessMonitor.vcproj
- SccProjectName5 = \u0022$/CommonAgents-2005/ProcessMonitor\u0022,\u0020VPACAAAA
- SccLocalPath5 = ProcessMonitor
- SccProvider5 = MSSCCI:Microsoft\u0020Visual\u0020SourceSafe
- SccProjectUniqueName6 = RavenClaw\\RavenClaw.vcproj
- SccProjectName6 = \u0022$/CommonAgents-2005/RavenClaw\u0022,\u0020PRACAAAA
- SccLocalPath6 = RavenClaw
- SccProvider6 = MSSCCI:Microsoft\u0020Visual\u0020SourceSafe
- SccProjectUniqueName7 = MultiDecoder\\Sphinx_Engine\\Sphinx_Engine.vcproj
- SccProjectName7 = \u0022$/CommonAgents-2005/MultiDecoder/Sphinx_Engine\u0022,\u0020BOACAAAA
- SccLocalPath7 = MultiDecoder\\Sphinx_Engine
- SccProvider7 = MSSCCI:Microsoft\u0020Visual\u0020SourceSafe
- EndGlobalSection
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Release|Win32 = Release|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {C31484B0-179B-432D-AE1E-75FB90591F23}.Debug|Win32.ActiveCfg = Debug|Win32
- {C31484B0-179B-432D-AE1E-75FB90591F23}.Debug|Win32.Build.0 = Debug|Win32
- {C31484B0-179B-432D-AE1E-75FB90591F23}.Release|Win32.ActiveCfg = Debug|Win32
- {C31484B0-179B-432D-AE1E-75FB90591F23}.Release|Win32.Build.0 = Debug|Win32
- {93C8F5F8-6C43-4179-9B9F-A31AA6438513}.Debug|Win32.ActiveCfg = Debug|Win32
- {93C8F5F8-6C43-4179-9B9F-A31AA6438513}.Debug|Win32.Build.0 = Debug|Win32
- {93C8F5F8-6C43-4179-9B9F-A31AA6438513}.Release|Win32.ActiveCfg = Release|Win32
- {93C8F5F8-6C43-4179-9B9F-A31AA6438513}.Release|Win32.Build.0 = Release|Win32
- {9CDBFBA5-F7EB-432F-A7CF-2E80322FE2ED}.Debug|Win32.ActiveCfg = SwiftDebug|Win32
- {9CDBFBA5-F7EB-432F-A7CF-2E80322FE2ED}.Debug|Win32.Build.0 = SwiftDebug|Win32
- {9CDBFBA5-F7EB-432F-A7CF-2E80322FE2ED}.Release|Win32.ActiveCfg = SwiftRelease|Win32
- {9CDBFBA5-F7EB-432F-A7CF-2E80322FE2ED}.Release|Win32.Build.0 = SwiftRelease|Win32
- {AB3C8BF7-BF9D-4A80-A956-E969B9D8542D}.Debug|Win32.ActiveCfg = Debug|Win32
- {AB3C8BF7-BF9D-4A80-A956-E969B9D8542D}.Debug|Win32.Build.0 = Debug|Win32
- {AB3C8BF7-BF9D-4A80-A956-E969B9D8542D}.Release|Win32.ActiveCfg = Release|Win32
- {AB3C8BF7-BF9D-4A80-A956-E969B9D8542D}.Release|Win32.Build.0 = Release|Win32
- {7022E28A-B15B-4A61-876A-5962C8EC1219}.Debug|Win32.ActiveCfg = Debug|Win32
- {7022E28A-B15B-4A61-876A-5962C8EC1219}.Debug|Win32.Build.0 = Debug|Win32
- {7022E28A-B15B-4A61-876A-5962C8EC1219}.Release|Win32.ActiveCfg = Release|Win32
- {7022E28A-B15B-4A61-876A-5962C8EC1219}.Release|Win32.Build.0 = Release|Win32
- {4051C912-8C55-442F-9AF8-3F3AE9859776}.Debug|Win32.ActiveCfg = Debug|Win32
- {4051C912-8C55-442F-9AF8-3F3AE9859776}.Debug|Win32.Build.0 = Debug|Win32
- {4051C912-8C55-442F-9AF8-3F3AE9859776}.Release|Win32.ActiveCfg = Release|Win32
- {4051C912-8C55-442F-9AF8-3F3AE9859776}.Release|Win32.Build.0 = Release|Win32
- {73E306B4-6227-4843-8A59-9B85C382790C}.Debug|Win32.ActiveCfg = Debug|Win32
- {73E306B4-6227-4843-8A59-9B85C382790C}.Debug|Win32.Build.0 = Debug|Win32
- {73E306B4-6227-4843-8A59-9B85C382790C}.Release|Win32.ActiveCfg = Release|Win32
- {73E306B4-6227-4843-8A59-9B85C382790C}.Release|Win32.Build.0 = Release|Win32
- {538B76FD-E289-4CF7-A7FF-1ACB429B4F63}.Debug|Win32.ActiveCfg = DebugGalaxy|Win32
- {538B76FD-E289-4CF7-A7FF-1ACB429B4F63}.Debug|Win32.Build.0 = DebugGalaxy|Win32
- {538B76FD-E289-4CF7-A7FF-1ACB429B4F63}.Release|Win32.ActiveCfg = ReleaseGalaxy|Win32
- {538B76FD-E289-4CF7-A7FF-1ACB429B4F63}.Release|Win32.Build.0 = ReleaseGalaxy|Win32
- {6A7673C4-08F4-4490-93A5-5F7211B406CF}.Debug|Win32.ActiveCfg = Debug|Win32
- {6A7673C4-08F4-4490-93A5-5F7211B406CF}.Debug|Win32.Build.0 = Debug|Win32
- {6A7673C4-08F4-4490-93A5-5F7211B406CF}.Release|Win32.ActiveCfg = Release|Win32
- {6A7673C4-08F4-4490-93A5-5F7211B406CF}.Release|Win32.Build.0 = Release|Win32
{596C5D37-C409-4C46-BA28-B7F5EFB96851}.Debug|Win32.ActiveCfg = Debug|Win32
{596C5D37-C409-4C46-BA28-B7F5EFB96851}.Debug|Win32.Build.0 = Debug|Win32
{596C5D37-C409-4C46-BA28-B7F5EFB96851}.Release|Win32.ActiveCfg = Release|Win32
@@ -123,6 +33,10 @@
{8AD2EDB1-F154-40E3-8317-6799592E8B34}.Debug|Win32.Build.0 = Debug|Win32
{8AD2EDB1-F154-40E3-8317-6799592E8B34}.Release|Win32.ActiveCfg = Release|Win32
{8AD2EDB1-F154-40E3-8317-6799592E8B34}.Release|Win32.Build.0 = Release|Win32
+ {4051C912-8C55-442F-9AF8-3F3AE9859776}.Debug|Win32.ActiveCfg = Debug|Win32
+ {4051C912-8C55-442F-9AF8-3F3AE9859776}.Debug|Win32.Build.0 = Debug|Win32
+ {4051C912-8C55-442F-9AF8-3F3AE9859776}.Release|Win32.ActiveCfg = Release|Win32
+ {4051C912-8C55-442F-9AF8-3F3AE9859776}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Modified: TeamTalk/Agents/PenDecoder/src/edu/cmu/ravenclaw/pendecoder/BotShape.java
===================================================================
--- TeamTalk/Agents/PenDecoder/src/edu/cmu/ravenclaw/pendecoder/BotShape.java 2007-02-25 14:08:57 UTC (rev 568)
+++ TeamTalk/Agents/PenDecoder/src/edu/cmu/ravenclaw/pendecoder/BotShape.java 2007-04-05 16:56:50 UTC (rev 569)
@@ -47,9 +47,18 @@
* robot goal location in robot's coordinate system (in centimeters)
*/
protected float goalx, goaly;
- protected boolean goal_seeking;
/**
+ * current goal taskid
+ */
+ protected int taskid;
+
+ /**
+ * current goal status
+ */
+ protected TaskStatus goal_status;
+
+ /**
* last known good position and orientation of robot (in centimeters and radians)
* when the uncertainty about the robots position and orientation reach some threashhold
* we just keep showing this last known good postition
@@ -68,6 +77,7 @@
protected static Color unselected_color = Color.RED;
protected static Color selected_color = Color.YELLOW;
+ protected static Color failed_color = Color.WHITE;
protected Color distinct_color = null;
public static final Font labelFont = new Font("Lucida Sans", Font.BOLD, 14);
public static final Font uncertainFont = new Font("Lucida Sans", Font.ITALIC, 14);
@@ -76,7 +86,7 @@
public BotShape(String name, ColorGenerator cg) {
super(unselected_color, name);
if(cg != null) distinct_color = cg.getNextDistinctColor();
- goal_seeking = false;
+ goal_status = null;
makeIcon();
setLocation(0F, 0F, 0F);
try {
@@ -89,7 +99,7 @@
public BotShape(String name, ColorGenerator cg, int x, int y, float rad) {
super(unselected_color, name);
if(cg != null) distinct_color = cg.getNextDistinctColor();
- goal_seeking = false;
+ goal_status = null;
makeIcon();
setLocation(0F, 0F, 0F);
try {
@@ -134,7 +144,7 @@
placedUncertaintyRing = move.createTransformedShape(uncertaintyRing);
//reset goal
- goal_seeking = false;
+ goal_status = null;
//reset composite
composite = AlphaComposite.getInstance(AlphaComposite.SRC_OVER);
@@ -153,7 +163,8 @@
}
protected java.awt.Shape getPlacedArrowShape(int dist, float angle) {
- int[] xs = new int[] {50, dist-30, dist-30, dist, dist-30, dist-30, 50};
+ int tail = (dist > 50? 50: dist-50);
+ int[] xs = new int[] {tail, dist-30, dist-30, dist, dist-30, dist-30, tail};
int[] ys = new int[] {12, 12, 24, 0, -24, -12, -12};
AffineTransform move = new AffineTransform(placement);
move.translate(x,y);
@@ -183,22 +194,19 @@
g.setColor(Color.black);
g.fill(placedDot);
- //draw goal arrow if distance to goal is greater than 1 meter (100 cm)
- if(goal_seeking) {
+ //draw goal arrow
+ if(goal_status == TaskStatus.FAILED || goal_status == TaskStatus.IN_PROGRESS) {
int distance = (int)Math.sqrt((goalx-x)*(goalx-x)+(goaly-y)*(goaly-y));
- if(distance < 100) {
- goal_seeking = false;
+ java.awt.Shape arrow = getPlacedArrowShape(distance, (float)Math.atan2(goaly-y, goalx-x));
+ if(goal_status == TaskStatus.FAILED) {
+ g.setColor(failed_color);
+ } else if(selected) {
+ g.setColor(selected_color);
} else {
- System.err.println("Drawing arrow");
- java.awt.Shape arrow = getPlacedArrowShape(distance, (float)Math.atan2(goaly-y, goalx-x));
- if(selected) {
- g.setColor(selected_color);
- } else {
- g.setColor(unselected_color);
- }
- if(alpha > 0.5F) g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.5F));
- g.fill(arrow);
+ g.setColor(unselected_color);
}
+ if(alpha > 0.5F) g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.5F));
+ g.fill(arrow);
}
//reset graphics context
@@ -311,19 +319,38 @@
* @param y y coordinate of robot's frame goal location (in centimeters)
*/
- public void setGoal(boolean relative, float x, float y) {
- System.err.println("Setting goal for bot " + x + ' ' + y);
- if(relative) {
- float a = (float)Math.atan2(y, x) + rad;
- int dist = (int)Math.sqrt(x*x+y*y);
- goalx = this.x + (float)Math.cos(a)*dist;
- goaly = this.y + (float)Math.sin(a)*dist;
- } else {
- goalx = x;
- goaly = y;
+ public void setGoal(boolean relative, float x, float y, TaskStatus status, int taskid) {
+ System.err.println("Setting goal for bot " + x + ' ' + y + ' ' + status);
+ switch(status) {
+ case UNSENT:
+ break;
+ case UNACKED:
+ case IN_PROGRESS:
+ if(relative) {
+ float a = (float)Math.atan2(-y, x) + rad;
+ int dist = (int)Math.sqrt(x*x+y*y);
+ goalx = this.x + (float)Math.cos(a)*dist;
+ goaly = this.y + (float)Math.sin(a)*dist;
+ } else {
+ goalx = x;
+ goaly = y;
+ }
+ System.err.println("goalx " + goalx + " goaly " + goaly);
+ this.taskid = taskid;
+ goal_status = status;
+ break;
+ case ABANDONED:
+ case SUCCEEDED:
+ if(taskid == this.taskid) {
+ goal_status = null;
+ }
+ break;
+ case FAILED:
+ if(taskid == this.taskid) {
+ goal_status = status;
+ }
+ break;
}
- goal_seeking = true;
- System.err.println("goalx " + goalx + " goaly " + goaly);
}
/**
Modified: TeamTalk/Agents/PenDecoder/src/edu/cmu/ravenclaw/pendecoder/BotTracker.java
===================================================================
--- TeamTalk/Agents/PenDecoder/src/edu/cmu/ravenclaw/pendecoder/BotTracker.java 2007-02-25 14:08:57 UTC (rev 568)
+++ TeamTalk/Agents/PenDecoder/src/edu/cmu/ravenclaw/pendecoder/BotTracker.java 2007-04-05 16:56:50 UTC (rev 569)
@@ -61,14 +61,14 @@
return bot;
}
- public void setGoal(java.lang.String name, boolean relative, float x, float y) {
+ public void setGoal(java.lang.String name, boolean relative, float x, float y, TaskStatus status, int taskid) {
name.toUpperCase();
Shape s = bots.get(name);
if(s == null || !(s instanceof BotShape)) {
System.err.println("odd, bot set goal but can't be found: " + name);
} else {
BotShape bot = (BotShape) s;
- bot.setGoal(relative, x, y);
+ bot.setGoal(relative, x, y, status, taskid);
}
}
Modified: TeamTalk/Agents/PenDecoder/src/edu/cmu/ravenclaw/pendecoder/PenDecoderServer.java
===================================================================
--- TeamTalk/Agents/PenDecoder/src/edu/cmu/ravenclaw/pendecoder/PenDecoderServer.java 2007-02-25 14:08:57 UTC (rev 568)
+++ TeamTalk/Agents/PenDecoder/src/edu/cmu/ravenclaw/pendecoder/PenDecoderServer.java 2007-04-05 16:56:50 UTC (rev 569)
@@ -92,20 +92,20 @@
return (GFrame)null;
}
boolean bstatus = (status != 0);
- if(bstatus) frame.taskKeeper.succeedtask(taskid);
- else frame.taskKeeper.failtask(taskid);
+ if(bstatus)
+ frame.taskKeeper.changePendingTaskState(taskid, TaskStatus.SUCCEEDED);
+ else frame.taskKeeper.changePendingTaskState(taskid, TaskStatus.FAILED);
} else if(type.equalsIgnoreCase("ack")) {
- frame.taskKeeper.addTask(taskid);
+ frame.taskKeeper.addTask(taskid, TaskStatus.IN_PROGRESS);
} else {
System.err.println("unhandled trader message type: " + type);
return (GFrame)null;
}
//String active_rendering = null;
- String active_rendering = tk.utils.Utils.join(frame.taskKeeper.getActive(), " ");
- //for(Integer i : frame.taskKeeper.getActive()) active_rendering += i.toString() + ' ';
- //String succeeded_rendering = null;
- String succeeded_rendering = tk.utils.Utils.join(frame.taskKeeper.getSucceeded(), " ");
- //for(Integer i : frame.taskKeeper.getSucceeded()) succeeded_rendering += i.toString() + ' ';
+ String active_rendering =
+ tk.utils.Utils.join(frame.taskKeeper.get(TaskStatus.IN_PROGRESS), " ");
+ String succeeded_rendering =
+ tk.utils.Utils.join(frame.taskKeeper.get(TaskStatus.SUCCEEDED), " ");
frame.getInterpreter().print_bot("active tasks", active_rendering);
frame.getInterpreter().print_bot("succeeded tasks", succeeded_rendering);
return (GFrame) null;
@@ -117,8 +117,14 @@
//message come in meters. we operate in centimeter space
float x = 100*((Float)f.getProperty(":x")).floatValue();
float y = 100*((Float)f.getProperty(":y")).floatValue();
-
- botTracker.setGoal(name, relative, x, y);
+ int taskid = ((Integer)f.getProperty(":taskid")).intValue();
+ TaskStatus status;
+ try {
+ status = TaskStatus.valueOf((String)f.getProperty(":status"));
+ botTracker.setGoal(name, relative, x, y, status, taskid);
+ } catch (IllegalArgumentException e) {
+ System.err.println("Can't parse status: " + f.getProperty(":status"));
+ }
return (GFrame) null;
}
@@ -344,7 +350,6 @@
}
pgoNets.addElement(gfNet);
}
- //pgoNets.setSize(1);
//then construct the encompassing slot
gfSlot.setProperty(":nets", pgoNets);
@@ -353,7 +358,6 @@
gfSlot.setProperty(":contents", hyp); //this is bogus but so what?
gfSlot.setProperty(":frame", frame);
pgoSlots.addElement(gfSlot);
- //pgoSlots.setSize(1);
// then construct the encompassing parse
gfParse.setProperty(":slots", pgoSlots);
@@ -373,11 +377,9 @@
gfParse.setProperty(":avg_validwordconf", 0.0F);
gfParse.setProperty(":min_validwordconf", 0.0F);
gfParse.setProperty(":max_validwordconf", 0.0F);
- gfParse.setProperty(":parsestring",
- //frame + "\n" + slot + " ( " + net + " ( " + val + " ) )\n\n");
+ gfParse.setProperty(":parsestring",
frame + "\n" + slot + " " + parse + "\n\n");
pgoParses.addElement(gfParse);
- //pgoParses.setSize(1);
f.setProperty(":parses", pgoParses);
f.setProperty(":total_numparses", 1);
Modified: TeamTalk/Agents/PenDecoder/src/edu/cmu/ravenclaw/pendecoder/TaskKeeper.java
===================================================================
--- TeamTalk/Agents/PenDecoder/src/edu/cmu/ravenclaw/pendecoder/TaskKeeper.java 2007-02-25 14:08:57 UTC (rev 568)
+++ TeamTalk/Agents/PenDecoder/src/edu/cmu/ravenclaw/pendecoder/TaskKeeper.java 2007-04-05 16:56:50 UTC (rev 569)
@@ -10,6 +10,7 @@
package edu.cmu.ravenclaw.pendecoder;
+import java.util.EnumMap;
import java.util.LinkedList;
import java.util.List;
@@ -17,53 +18,30 @@
*
* @author tkharris
*/
-public class TaskKeeper {
- private List<Integer> activetasks = new LinkedList<Integer>();
- private List<Integer> failedtasks = new LinkedList<Integer>();
- private List<Integer> succeededtasks = new LinkedList<Integer>();
- private List<Integer> cancelledtasks = new LinkedList<Integer>();
+public class TaskKeeper extends EnumMap<TaskStatus, List<Integer>> {
/** Creates a new instance of TaskKeeper */
- public TaskKeeper() {}
-
- public void addTask(Integer taskid) {
- activetasks.add(taskid);
+ public TaskKeeper() {
+ super(TaskStatus.class);
}
- public void succeedtask(Integer taskid) {
- activetasks.remove(taskid);
- succeededtasks.add(taskid);
+ public void addTask(Integer taskid, TaskStatus status) {
+ get(status).add(taskid);
}
- public void failtask(Integer taskid) {
- activetasks.remove(taskid);
- failedtasks.add(taskid);
- }
-
- //boolean cancelLastTask() {
- // if(activetasks.isEmpty()) return false;
- // cancelledtasks.add(activetasks.remove(0));
- // return true;
- //}
-
- public List<Integer> getActive() {
- return activetasks;
- }
-
- public List<Integer> getSucceeded() {
- return succeededtasks;
- }
-
- public List<Integer> getFailed() {
- return failedtasks;
- }
-
- public List<Integer> getCancelled() {
- return cancelledtasks;
- }
-
+ public void changePendingTaskState(Integer taskid, TaskStatus status) {
+ if(!get(TaskStatus.IN_PROGRESS).remove(taskid)
+ && !get(TaskStatus.UNACKED).remove(taskid)
+ && !get(TaskStatus.UNSENT).remove(taskid))
+ System.err.println("couldn't find: " + taskid);
+
+ get(status).add(taskid);
+ }
+
public Integer getLastAdded() {
- if(activetasks.isEmpty()) return (Integer)null;
- return activetasks.get(activetasks.size()-1);
+ if(get(TaskStatus.IN_PROGRESS).isEmpty()) return (Integer)null;
+ return get(TaskStatus.IN_PROGRESS).get(get(TaskStatus.IN_PROGRESS).size()-1);
}
+
+ private static final long serialVersionUID = 2916483434314857716L;
}
Modified: TeamTalk/Agents/PrimitiveComm/robot_client.cpp
===================================================================
--- TeamTalk/Agents/PrimitiveComm/robot_client.cpp 2007-02-25 14:08:57 UTC (rev 568)
+++ TeamTalk/Agents/PrimitiveComm/robot_client.cpp 2007-04-05 16:56:50 UTC (rev 569)
@@ -68,7 +68,7 @@
warn << "couldn't reconnect to " << me->getHost() << ':' << me->getPort() << endl;
}
}
- if(!(t%40) && me->hasCamera()) { //send image request every 40 seconds
+ if(me->hasCamera()) { //send image request every second
me->sendReqImage();
}
}
Modified: TeamTalk/Agents/PrimitiveComm/robot_packet2.cpp
===================================================================
--- TeamTalk/Agents/PrimitiveComm/robot_packet2.cpp 2007-02-25 14:08:57 UTC (rev 568)
+++ TeamTalk/Agents/PrimitiveComm/robot_packet2.cpp 2007-04-05 16:56:50 UTC (rev 569)
@@ -23,26 +23,50 @@
const char* MalformedPacketException::what() throw() {return error.c_str();}
-// Msg ****************************************************************
+// TaskStatus *********************************************************
-int Msg::boeingStatus(Msg::Status x)
+const char* TaskStatus::map_[] =
+ {"ABANDONED", "FAILED", "UNSENT", "UNACKED", "IN_PROGRESS", "SUCCEEDED"};
+
+TaskStatus::TaskStatus() : status_(TaskStatus::UNSENT) {}
+TaskStatus::TaskStatus(TaskStatus::Enum x) : status_(x) {}
+
+int TaskStatus::boeingStatus(TaskStatus x)
{
- switch(x) {
+ switch(x.status_) {
+ case ABORTED: return Boeing::ABORTED;
case FAILED: return Boeing::FAILED;
+ case UNSENT:
+ case UNACKED:
case IN_PROGRESS: return Boeing::INPROGRESS;
case SUCCEEDED: return Boeing::SUCCEEDED;
- default: error << "unknown status " << (int)x;
+ default: error << "unknown status " << x;
}
return 0;
}
-Msg::Status Msg::statusOfBoeing(int x)
+TaskStatus TaskStatus::statusOfBoeing(int x)
{
- if(x <= Boeing::FAILED) return FAILED;
+ if(x == Boeing::ABORTED) return TaskStatus(ABORTED);
+ if(x == Boeing::FAILED) return TaskStatus(FAILED);
if(x >= Boeing::SUCCEEDED) return SUCCEEDED;
return IN_PROGRESS;
}
+TaskStatus TaskStatus::operator=(TaskStatus::Enum x) {
+ status_ = x;
+ return *this;
+}
+
+TaskStatus::operator const char *() const {return map_[status_];}
+
+bool TaskStatus::isInProgress() const {return status_ == IN_PROGRESS;}
+bool TaskStatus::isFailed() const {return status_ == FAILED;}
+bool TaskStatus::isAborted() const {return status_ == ABORTED;}
+bool TaskStatus::isSuccess() const {return status_ == SUCCEEDED;}
+
+// Msg ****************************************************************
+
int Msg::taskIDCounter = 0;
const int Msg::defaultPriority = 1;
@@ -130,8 +154,16 @@
if(type == Boeing::ROB_DONE) {
debug("packet") << "got: ROB_DONE" << endl;
const Boeing::MsgRobDone* bp = reinterpret_cast<const Boeing::MsgRobDone*>(m.c_str());
- return new MsgRobDone(sender, tstamp,
- bp->taskid, (bp->status == Boeing::SUCCEEDED));
+ if(bp->status == Boeing::SUCCEEDED)
+ return new MsgRobDone(sender, tstamp, bp->taskid, TaskStatus::SUCCEEDED);
+ else if(bp->status == Boeing::FAILED)
+ return new MsgRobDone(sender, tstamp, bp->taskid, TaskStatus::FAILED);
+ else if(bp->status == Boeing::ABORTED)
+ return new MsgRobDone(sender, tstamp, bp->taskid, TaskStatus::ABORTED);
+ else {
+ error << "couldn't get Boeing::ROB_DONE status" << endl;
+ return NULL;
+ }
}
if(type == Boeing::ROB_PLAY_HALT) {
warn("packet") << "unhandled type: ROB_PLAY_HALT " << endl;
@@ -198,11 +230,19 @@
: Msg(sender), taskID_(taskIDCounter++), priority_(priority) {}
//instantiation from Boeing packet
MsgCmd::MsgCmd(string sender, double tstamp, int priority, int taskID)
-: Msg(sender, tstamp) {}
+: Msg(sender, tstamp), taskID_(taskID), priority_(priority),
+ status_(TaskStatus::IN_PROGRESS) {}
int MsgCmd::getTaskID() const {return taskID_;}
int MsgCmd::getPriority() const {return priority_;}
+void MsgCmd::setStatus(TaskStatus status) {status_ = status;}
+void MsgCmd::setStatus(const MsgRobDone* done) {
+ status_ = done->getStatus();
+ sender_ = done->getSender();
+}
+TaskStatus MsgCmd::getStatus() const {return status_;}
+
MsgCmd* MsgCmd::interpretBoeingPlayAction(const Boeing::MsgCmdAction* m,
const string& sender, double tstamp)
{
@@ -239,10 +279,10 @@
string MsgCmd::render() const
{
ostringstream out;
- out << "MsgCmd: ";
- out << "sender " << sender_;
- out << " priority " << priority_;
- out << " tstamp " << tstamp_ << ' ';
+ out << "MsgCmd: #" << taskID_;
+ out << " sender(" << sender_;
+ out << ") priority(" << priority_;
+ out << ") tstamp(" << tstamp_ << ") ";
out << renderBoeingPlayAction();
return out.str();
}
@@ -464,21 +504,18 @@
// MsgRobActionAck ****************************************************
//normal instantiation
-MsgRobActionAck::MsgRobActionAck(int taskID, Status status, string sender)
+MsgRobActionAck::MsgRobActionAck(int taskID, TaskStatus status, string sender)
: Msg(sender), taskID_(taskID), status_(status) {}
//instantiation from a Boeing packet
MsgRobActionAck::MsgRobActionAck(string sender, double tstamp, int taskID, int status)
-: Msg(sender, tstamp), taskID_(taskID), status_(statusOfBoeing(status)) {}
+: Msg(sender, tstamp), taskID_(taskID),
+ status_(TaskStatus::statusOfBoeing(status)) {}
int MsgRobActionAck::getTaskID() const {return taskID_;}
-Msg::Status MsgRobActionAck::getStatus() const {return status_;}
+TaskStatus MsgRobActionAck::getStatus() const {return status_;}
-bool MsgRobActionAck::isSuccess() const {return status_ == SUCCEEDED;}
-bool MsgRobActionAck::isInprogress() const {return status_ == IN_PROGRESS;}
-bool MsgRobActionAck::isFailure() const {return status_ == FAILED;}
-
string MsgRobActionAck::render() const {
ostringstream out;
out << "robactionack: " << taskID_ << status_;
@@ -486,32 +523,34 @@
}
string MsgRobActionAck::renderBoeingPacket() const {
- Boeing::MsgActionAck packet = Boeing::MsgActionAck::factory(taskID_, statusOfBoeing(status_));
+ Boeing::MsgActionAck packet =
+ Boeing::MsgActionAck::factory(taskID_, TaskStatus::boeingStatus(status_));
return string(reinterpret_cast<char *>(&packet), packet.len);
}
// MsgRobDone *********************************************************
//normal instantiation
-MsgRobDone::MsgRobDone(int taskID, bool success, string sender)
-: Msg(sender), taskID_(taskID), success_(success) {}
+MsgRobDone::MsgRobDone(int taskID, TaskStatus status, string sender)
+: Msg(sender), taskID_(taskID), status_(status) {}
//instantiation from a Boeing packet
-MsgRobDone::MsgRobDone(string sender, double tstamp, int taskID, bool success)
-: Msg(sender, tstamp), taskID_(taskID), success_(success) {}
+MsgRobDone::MsgRobDone(string sender, double tstamp, int taskID, TaskStatus status)
+: Msg(sender, tstamp), taskID_(taskID), status_(status) {}
int MsgRobDone::getTaskID() const {return taskID_;}
-bool MsgRobDone::isSuccess() const {return success_;}
-
+TaskStatus MsgRobDone::getStatus() const {return status_;}
+
string MsgRobDone::render() const {
ostringstream out;
- out << "robdone: " << taskID_ << (success_? "SUCCEEDED": "FAILED");
+ out << "robdone: " << taskID_ << ' ' << status_;
return out.str();
}
string MsgRobDone::renderBoeingPacket() const {
- Boeing::MsgRobDone packet = Boeing::MsgRobDone::factory(taskID_, success_);
+ Boeing::MsgRobDone packet =
+ Boeing::MsgRobDone::factory(taskID_, TaskStatus::boeingStatus(status_));
return string(reinterpret_cast<char *>(&packet), packet.len);
}
@@ -644,6 +683,7 @@
return out << m->render();
}
+/*
ostream& operator<<(ostream& out, const Msg::Status& x)
{
switch(x)
@@ -662,3 +702,4 @@
}
return out;
}
+*/
\ No newline at end of file
Modified: TeamTalk/Agents/PrimitiveComm/robot_packet2.h
===================================================================
--- TeamTalk/Agents/PrimitiveComm/robot_packet2.h 2007-02-25 14:08:57 UTC (rev 568)
+++ TeamTalk/Agents/PrimitiveComm/robot_packet2.h 2007-04-05 16:56:50 UTC (rev 569)
@@ -17,6 +17,8 @@
*
* MalformedPacketException -- a packet is unparseble
*
+ * TaskStatus -- task status
+ *
* Msg -- message superclass (abstract)
* MsgCmd -- superclass for command messages sent to robots (abstract)
* MsgCmdHalt
@@ -43,12 +45,26 @@
const char* what() throw();
};
+class TaskStatus {
+public:
+ enum Enum {ABORTED, FAILED, UNSENT, UNACKED, IN_PROGRESS, SUCCEEDED};
+protected:
+ Enum status_;
+ static const char* map_[6];
+public:
+ TaskStatus();
+ TaskStatus(TaskStatus::Enum x);
+ static int boeingStatus(TaskStatus x);
+ static TaskStatus statusOfBoeing(int x);
+ TaskStatus operator=(TaskStatus::Enum x);
+ operator const char*() const;
+ bool isInProgress() const;
+ bool isFailed() const;
+ bool isAborted() const;
+ bool isSuccess() const;
+};
class Msg {
-public:
- enum Status {FAILED, IN_PROGRESS, SUCCEEDED};
- static int boeingStatus(Status x);
- static Status statusOfBoeing(int x);
protected:
static const int defaultPriority;
@@ -72,10 +88,27 @@
virtual string render() const =0;
};
+class MsgRobDone : public Msg {
+protected:
+ int taskID_;
+ TaskStatus status_;
+public:
+ //normal instantiation
+ MsgRobDone(int taskID, TaskStatus status=TaskStatus::SUCCEEDED,
+ string sender=string());
+ //instantiation from a Boeing packet
+ MsgRobDone(string sender, double tstamp, int taskID, TaskStatus status);
+ int getTaskID() const;
+ TaskStatus getStatus() const;
+ string render() const;
+ string renderBoeingPacket() const;
+};
+
class MsgCmd : public Msg {
protected:
int taskID_;
int priority_;
+ TaskStatus status_;
//normal instantiation
MsgCmd();
@@ -88,6 +121,11 @@
int getPriority() const;
static MsgCmd* interpretBoeingPlayAction(const Boeing::MsgCmdAction* m,
const string& sender, double tstamp);
+
+ void setStatus(TaskStatus status);
+ void setStatus(const MsgRobDone* done);
+ TaskStatus getStatus() const;
+
string renderBoeingPacket() const;
virtual string renderBoeingPlayAction() const =0;
string render() const;
@@ -120,6 +158,7 @@
float getX() const;
float getY() const;
float getAngle() const;
+ float getDistance() const;
bool useAngle() const;
bool isAbsolute() const;
bool isRelative() const;
@@ -219,36 +258,18 @@
class MsgRobActionAck : public Msg {
protected:
int taskID_;
- Status status_;
+ TaskStatus status_;
public:
//normal instantiation
- MsgRobActionAck(int taskID, Status status, string sender=string());
+ MsgRobActionAck(int taskID, TaskStatus status, string sender=string());
//instantiation from a Boeing packet
MsgRobActionAck(string sender, double tstamp, int taskID, int status);
int getTaskID() const;
- Status getStatus() const;
- bool isSuccess() const;
- bool isFailure() const;
- bool isInprogress() const;
+ TaskStatus getStatus() const;
string render() const;
string renderBoeingPacket() const;
};
-class MsgRobDone : public Msg {
-protected:
- int taskID_;
- bool success_;
-public:
- //normal instantiation
- MsgRobDone(int taskID, bool success=true, string sender=string());
- //instantiation from a Boeing packet
- MsgRobDone(string sender, double tstamp, int taskID, bool success);
- int getTaskID() const;
- bool isSuccess() const;
- string render() const;
- string renderBoeingPacket() const;
-};
-
class MsgRobLocation : public Msg {
protected:
static const float tolerance;
@@ -312,6 +333,5 @@
};
ostream& operator<<(ostream& out, const Msg* m);
-ostream& operator<<(ostream& out, const Msg::Status& x);
#endif
Modified: TeamTalk/Agents/TeamTalkBackend/agent.cpp
===================================================================
--- TeamTalk/Agents/TeamTalkBackend/agent.cpp 2007-02-25 14:08:57 UTC (rev 568)
+++ TeamTalk/Agents/TeamTalkBackend/agent.cpp 2007-04-05 16:56:50 UTC (rev 569)
@@ -1,10 +1,14 @@
#include "agent.h"
#include <utils.h>
+#ifdef WIN32
+#include <win32dep.h>
+#endif
#include <sstream>
#include <fstream>
#include <iomanip>
#include <ios>
+#include <cmath>
#define USE_TXT_COMMANDS
@@ -73,6 +77,13 @@
serverChildren_.push(spawn(false, cfilename, ".", DM, args.str()).hProcess);
}
+vector<MsgCmd*>::iterator Agent::findMsgById(int taskid) {
+ vector<MsgCmd*>::iterator i;
+ for(i = commitments_.begin(); i != commitments_.end(); i++)
+ if((*i)->getTaskID() == taskid) break;
+ return i;
+}
+
string Agent::writeSpecializedConfig(const string temp, const string ext,
const map<string, string>& subs,
const string name)
@@ -127,6 +138,8 @@
Gal_SetProp(f, ":relative", Gal_IntObject(move->isRelative()? 1: 0));
Gal_SetProp(f, ":x", Gal_FloatObject((float)move->getX()));
Gal_SetProp(f, ":y", Gal_FloatObject((float)move->getY()));
+ Gal_SetProp(f, ":status", Gal_StringObject(move->getStatus()));
+ Gal_SetProp(f, ":taskid", Gal_IntObject(move->getTaskID()));
return f;
}
@@ -148,6 +161,7 @@
Gal_SetProp(f, ":relative", Gal_IntObject(0));
Gal_SetProp(f, ":x", Gal_FloatObject(0));
Gal_SetProp(f, ":y", Gal_FloatObject(0));
+ Gal_SetProp(f, ":status", Gal_StringObject(home->getStatus()));
return f;
}
@@ -157,6 +171,7 @@
f = Gal_MakeFrame("robot_message", GAL_CLAUSE);
Gal_SetProp(f, ":type", Gal_StringObject("follow"));
Gal_SetProp(f, ":robot_name", Gal_StringObject(follow->getSender().c_str()));
+ Gal_SetProp(f, ":status", Gal_StringObject(follow->getStatus()));
//string host = follow->content()->leader;
//string::size_type i = host.find(':');
//int port = 0;
@@ -183,6 +198,7 @@
}
Gal_SetProp(f, ":x", Gal_ListObject(xs, (int)polygon.size()));
Gal_SetProp(f, ":y", Gal_ListObject(ys, (int)polygon.size()));
+ Gal_SetProp(f, ":status", Gal_StringObject(cover->getStatus()));
return f;
}
@@ -227,12 +243,29 @@
void Agent::processMessage(const Msg* m)
{
+ Gal_Frame f;
const MsgRobLocation *rloc = dynamic_cast<const MsgRobLocation*>(m);
if(rloc != NULL) {
if(location_ == *rloc) return;
location_ = *rloc;
}
- Gal_Frame f = galaxyFrame(m);
+ const MsgCmdGoTo *move = dynamic_cast<const MsgCmdGoTo*>(m);
+ if(move != NULL) SendMoveStatusToDM(move);
+ const MsgRobDone *done = dynamic_cast<const MsgRobDone*>(m);
+ if(done != NULL) {
+ vector<MsgCmd*>::iterator i = findMsgById(done->getTaskID());
+ if(i == commitments_.end()) {
+ error << "Can't fine msg with taskid: " << done->getTaskID() << endl;
+ return;
+ } else {
+ (*i)->setStatus(done);
+ f = galaxyFrame(*i);
+ const MsgCmdGoTo* move = dynamic_cast<const MsgCmdGoTo*>(*i);
+ if(move != NULL) SendMoveStatusToDM(move);
+ delete *i;
+ commitments_.erase(i);
+ }
+ } else f = galaxyFrame(m);
char *frame_name = Gal_FrameName(f);
if(frame_name != NULL && !strcmp(frame_name, "robot_message")) {
debug << "sending to '" << name_ << "' hub: " << m->render() << endl;
@@ -250,8 +283,18 @@
// message towards the DM: The message will be
// emulating a phoenix parse, of the form
// RobotMessage [RobotMessage] ( [MsgType] ( Message ) )
-void Agent::SendMessageToDM(string sMsgType, string sMessage) const
+void Agent::SendMessageToDM(const string& sMsgType, const string& sMessage) const
{
+ map<string, string> sMessages;
+ sMessages[sMsgType] = sMessage;
+ SendMessageToDM("RobotMessage", sMessages);
+}
+
+// [2007-04-02] (tk): modified to construct a message with multiple nets, i.e.:
+// RobotMessage [sMsgType] ( [Var1] ( Val1 ) [Var2] ( Val2 )... ) )
+void Agent::SendMessageToDM(const string& sMsgType,
+ const map<string, string>& sMessages) const
+{
// variables holding the nested galaxy parse frame
Gal_Frame gfInput, gfParse, gfSlot, gfNet;
Gal_Object *pgoParses, *pgoSlots, *pgoNets;
@@ -265,20 +308,33 @@
pgoSlots = (Gal_Object *)malloc(sizeof(Gal_Object));
gfSlot = Gal_MakeFrame("slot", GAL_CLAUSE);
- pgoNets = (Gal_Object *)malloc(sizeof(Gal_Object));
- gfNet = Gal_MakeFrame("net", GAL_CLAUSE);
+ pgoNets = (Gal_Object *)calloc(sMessages.size(), sizeof(Gal_Object));
- // construct the net
- string sNetName = " " + sMsgType + " ";
- Gal_SetProp(gfNet, ":name", Gal_StringObject(sNetName.c_str()));
- Gal_SetProp(gfNet, ":contents", Gal_StringObject(sMessage.c_str()));
- pgoNets[0] = Gal_FrameObject(gfNet);
+ string hyp;
+ string parse;
+ // construct the nets
+ map<string, string>::const_iterator smi = sMessages.begin();
+ for(int i = 0; smi != sMessages.end(); smi++, i++) {
+ if(i) {
+ hyp.append(" ");
+ parse.append(" ");
+ }
+ gfNet = Gal_MakeFrame("net", GAL_CLAUSE);
+ string sNetName = " " + smi->first + " ";
+ Gal_SetProp(gfNet, ":name", Gal_StringObject(sNetName.c_str()));
+ Gal_SetProp(gfNet, ":contents", Gal_StringObject(smi->second.c_str()));
+ hyp.append(smi->second);
+ parse.append("( " + smi->first + "( " + smi->second + " ) )");
+ pgoNets[i] = Gal_FrameObject(gfNet);
+ }
+
// then construct the encompassing slot
- Gal_SetProp(gfSlot, ":nets", Gal_ListObject(pgoNets, 1));
- Gal_SetProp(gfSlot, ":numnets", Gal_IntObject(1));
- Gal_SetProp(gfSlot, ":name", Gal_StringObject(" RobotMessage "));
- Gal_SetProp(gfSlot, ":contents", Gal_StringObject(sMessage.c_str()));
+ Gal_SetProp(gfSlot, ":nets", Gal_ListObject(pgoNets, (int)sMessages.size()));
+ Gal_SetProp(gfSlot, ":numnets", Gal_IntObject((int)sMessages.size()));
+ string sNetName = " " + sMsgType + " ";
+ Gal_SetProp(gfSlot, ":name", Gal_StringObject(sNetName.c_str()));
+ Gal_SetProp(gfSlot, ":contents", Gal_StringObject(hyp.c_str()));
Gal_SetProp(gfSlot, ":frame", Gal_StringObject(" RobotMessage "));
pgoSlots[0] = Gal_FrameObject(gfSlot);
@@ -286,7 +342,7 @@
Gal_SetProp(gfParse, ":slots", Gal_ListObject(pgoSlots, 1));
Gal_SetProp(gfParse, ":numslots", Gal_IntObject(1));
Gal_SetProp(gfParse, ":uttid", Gal_StringObject("-1"));
- Gal_SetProp(gfParse, ":hyp", Gal_StringObject(sMessage.c_str()));
+ Gal_SetProp(gfParse, ":hyp", Gal_StringObject(hyp.c_str()));
Gal_SetProp(gfParse, ":hyp_index", Gal_IntObject(0));
Gal_SetProp(gfParse, ":hyp_num_parses", Gal_IntObject(1));
Gal_SetProp(gfParse, ":decoder_score", Gal_FloatObject(0));
@@ -300,22 +356,63 @@
Gal_SetProp(gfParse, ":avg_validwordconf", Gal_FloatObject(0));
Gal_SetProp(gfParse, ":min_validwordconf", Gal_FloatObject(0));
Gal_SetProp(gfParse, ":max_validwordconf", Gal_FloatObject(0));
- string sParseString = "RobotMessage [RobotMessage] ( [" +
- sMsgType + "] ( " + sMessage + " ) )\n\n";
+ string sParseString = "RobotMessage \n" + sMsgType + " " + parse + "\n\n";
Gal_SetProp(gfParse, ":parsestring", Gal_StringObject(sParseString.c_str()));
pgoParses[0] = Gal_FrameObject(gfParse);
Gal_SetProp(gfInput, ":parses", Gal_ListObject(pgoParses, 1));
Gal_SetProp(gfInput, ":total_numparses", Gal_IntObject(1));
- Gal_SetProp(gfInput, ":input_source", Gal_StringObject("zap2Backend"));
+ Gal_SetProp(gfInput, ":input_source", Gal_StringObject("TeamTalkBackend"));
// finally, write it to the hub
- //writeFrameAllHubs(gfInput);
writeFrame(gfInput);
+
+ //and free everything
+ Gal_FreeFrame(gfInput);
+ free(pgoParses);
+ free(pgoSlots);
+ free(pgoNets);
}
+void Agent::SendMoveStatusToDM(const MsgCmdGoTo* move) const {
+ ostringstream move_report;
+ if(move->useAngle()) {
+ move_report << "Turn in place";
+ float angle = abs(fmodf(move->getAngle(), 2*(float)PI));
+ const float tol = (float)PI/8;
+ if(angle < PI-tol/2) move_report << " right";
+ else if(angle > PI+tol/2) move_report << " left";
+ move_report << ' ' << (int)(angle*180/PI) << " degrees";
+ } else if(move->isAbsolute()) {
+ move_report << "Movement to " << (int)move->getX() << ' ' << (int)move->getY();
+ } else {
+ move_report << "Movement";
+ float angle = (float)Point<float>(move->getX(), move->getY()).angle();
+ int cardinal = (int)((fmodf(angle + (float)PI/4, (float)PI)+PI)*2/PI);
+ debug << angle << ' ' << angle + (float)PI/4 << ' ' << fmodf(angle + (float)PI/4, (float)PI)
+ << ' ' << fmodf(angle + (float)PI/4, (float)PI)
+ << ' ' << fmodf(angle + (float)PI/4, (float)PI)+PI
+ << ' ' << (fmodf(angle + (float)PI/4, (float)PI)+PI)*2/PI
+ << ' ' << cardinal << endl;
+ const char* dir[4] = {" backward", " to the right", " forward", " to the left"};
+ move_report << ' ' << dir[cardinal];
+ float distance = round((float)Point<float>(move->getX(), move->getY()).length()*10)/10;
+ int major_d = (int)distance;
+ int minor_d = (int)(distance-major_d);
+ move_report << ' ' << major_d;
+ if(minor_d) move_report << '.' << minor_d;
+ move_report << " meters";
+ }
+ if(move->getStatus().isAborted()) move_report << " has been abandoned.";
+ else if(move->getStatus().isFailed()) move_report << " has failed.";
+ else if(move->getStatus().isInProgress()) move_report << " is now in progress.";
+ else if(move->getStatus().isSuccess()) move_report << " has been successfully completed.";
+ SendMessageToDM("MOVE", move_report.str());
+}
+
bool Agent::sendAction(const MsgCmd* cmd)
{
+ debug << "sending: " << cmd << endl;
return robotClient_->sendAction(cmd->getPriority(),
cmd->getTaskID(),
cmd->renderBoeingPlayAction().c_str());
@@ -434,6 +531,7 @@
s_direction == "BACKWARDS")
go = new MsgCmdGoTo(vec.rotate(PI));
if(go != NULL) {
+ commitments_.push_back(new MsgCmdGoTo(*go));
#ifdef USE_TXT_COMMANDS
sendAction(go);
#else
Modified: TeamTalk/Agents/TeamTalkBackend/agent.h
===================================================================
--- TeamTalk/Agents/TeamTalkBackend/agent.h 2007-02-25 14:08:57 UTC (rev 568)
+++ TeamTalk/Agents/TeamTalkBackend/agent.h 2007-04-05 16:56:50 UTC (rev 569)
@@ -26,10 +26,13 @@
MsgRobLocation location_;
string name_;
+ vector<MsgCmd*> commitments_;
+
protected:
static void spawnHub(const string& uppername);
static void spawnHelios(const string& uppername);
static void spawnDM(const string& uppername, const string& safeness);
+ vector<MsgCmd*>::iterator findMsgById(int taskid);
public:
static stack<HANDLE> serverChildren_;
@@ -58,8 +61,15 @@
// message towards the DM: The message will be
// emulating a phoenix parse, of the form
// RobotMessage [RobotMessage] ( [MsgType] ( Message ) )
- void SendMessageToDM(string sMsgType, string sMessage) const;
+ void SendMessageToDM(const string& sMsgType, const string& sMessage) const;
+ // [2007-04-02] (tk): emulate a little more complicated parse
+ // RobotMessage [RobotMessage] ( [MsgType] ( [Var1] (Val1) [Var2] (Val2)... ))
+ void SendMessageToDM(const string& sMsgType,
+ const map<string, string>& sMessages) const;
+
+ void SendMoveStatusToDM(const MsgCmdGoTo* move) const;
+
//processing incoming TeamTalk messages
void processMessage(const Msg* m);
static Gal_Frame galaxyFrame(const Msg* msgp);
Modified: TeamTalk/Agents/TeamTalkBackend/gal_be.cpp
===================================================================
--- TeamTalk/Agents/TeamTalkBackend/gal_be.cpp 2007-02-25 14:08:57 UTC (rev 568)
+++ TeamTalk/Agents/TeamTalkBackend/gal_be.cpp 2007-04-05 16:56:50 UTC (rev 569)
@@ -93,12 +93,15 @@
const char *user_id = Gal_GetString(f, ":user_id");
if(!user_id) error << "no user_id" << endl;
else if(!strcmp(user_id, "TeamTalk")) {
+ debug << "reinit: setting skeleton comm" << endl;
galaxyRobots->setSkeletonComm(GalSS_EnvComm((GalSS_Environment*)server_data));
restartDecoder();
galaxyRobots->setRobotVoices();
}
- else
+ else {
+ debug << "reinit: adding robot" << endl;
galaxyRobots->addRobot(user_id, GalSS_EnvComm((GalSS_Environment*)server_data));
+ }
return f;
}
Modified: TeamTalk/Agents/TeamTalkBackend/robot-galaxy_adapter.cpp
===================================================================
--- TeamTalk/Agents/TeamTalkBackend/robot-galaxy_adapter.cpp 2007-02-25 14:08:57 UTC (rev 568)
+++ TeamTalk/Agents/TeamTalkBackend/robot-galaxy_adapter.cpp 2007-04-05 16:56:50 UTC (rev 569)
@@ -3,8 +3,9 @@
#include <fstream>
//adds undiscoverable robots from a file
-void GalaxyRobots::processPeerfile(const string& fname)
+vector<string> GalaxyRobots::processPeerfile(const string& fname)
{
+ vector<string> names;
debug << "about to add robots" << endl;
ifstream Frobotips(fname.c_str());
if(!Frobotips) error << "problem opening " << fname << endl;
@@ -40,6 +41,8 @@
info << "adding robot@" << rip << ':' << port << ' ' << voice << ' ' << safeness << endl;
if(!r_client->addRobot(rname, rip, voice, safeness, port, this)) {
error << "couldn't add " << rname << endl;
+ } else {
+ names.push_back(rname);
}
}
} catch(TeamTalk::RobotClientException e) {
@@ -47,18 +50,26 @@
error << e.what() << endl;
}
}
+ return names;
}
-void GalaxyRobots::addRobotNamesToGrammar()
+void GalaxyRobots::addRobotNamesToGrammar(const vector<string>& names)
{
+ debug << "adding robot names to grammar:";
map<string, string> subs;
{
ostringstream gname;
+ /*
for(set<Agent>::const_iterator i = agents_.begin(); i != agents_.end(); i++) {
gname << " (" << tolower(i->getName()) << ')' << endl;
+ */
+ for(vector<string>::const_iterator i = names.begin(); i != names.end(); i++) {
+ gname << " (" << tolower(*i) << ')' << endl;
}
subs["%%RobotNames%%"] = gname.str();
+ debug << ' ' << gname.str();
}
+ debug << endl;
Agent::writeSpecializedConfig("..\\..\\Resources\\Grammar\\zap2Task", "gra",
subs);
@@ -241,10 +252,10 @@
//startup robot client
TeamTalk::RobotClient::spawnback = &Agent::spawnMinorGalaxy;
r_client = new TeamTalk::RobotsClient("tester");
- processPeerfile("peerfile.txt");
+ vector<string> names = processPeerfile("peerfile.txt");
if(!testLastConfig("peerfile.txt",
"..\\..\\Resources\\DecoderConfig\\LanguageModel\\zap2LM.arpa"))
- addRobotNamesToGrammar();
+ addRobotNamesToGrammar(names);
if(!m_client->isConnected()) {
fatal << "mapserver not found" << endl;
} else if(!m_client->sendSubscribe(0)) {
Modified: TeamTalk/Agents/TeamTalkBackend/robot-galaxy_adapter.h
===================================================================
--- TeamTalk/Agents/TeamTalkBackend/robot-galaxy_adapter.h 2007-02-25 14:08:57 UTC (rev 568)
+++ TeamTalk/Agents/TeamTalkBackend/robot-galaxy_adapter.h 2007-04-05 16:56:50 UTC (rev 569)
@@ -16,8 +16,8 @@
Boeing::MapClient *m_client; //the map server
protected:
- void processPeerfile(const string& fname);
- void addRobotNamesToGrammar();
+ vector<string> processPeerfile(const string& fname);
+ void addRobotNamesToGrammar(const vector<string>&);
//static bool testLastConfig(const string& source, const string& target);
Modified: TeamTalk/Agents/TeamTalkDM/zap2DialogTask.cpp
===================================================================
--- TeamTalk/Agents/TeamTalkDM/zap2DialogTask.cpp 2007-02-25 14:08:57 UTC (rev 568)
+++ TeamTalk/Agents/TeamTalkDM/zap2DialogTask.cpp 2007-04-05 16:56:50 UTC (rev 569)
@@ -307,6 +307,7 @@
BOOL_USER_CONCEPT(report_command_issued, "")
BOOL_USER_CONCEPT(report_location_command_issued, "")
STRING_SYSTEM_CONCEPT(location_report)
+ STRING_SYSTEM_CONCEPT(move_report)
BOOL_USER_CONCEPT(move_cardinal_command_issued, "")
BOOL_USER_CONCEPT(move_relative_command_issued, "")
BOOL_USER_CONCEPT(move_to_goal_command_issued, "")
@@ -330,7 +331,8 @@
SUBAGENT(MoveToGoal, CMoveToGoal, "")
SUBAGENT(Search, CSearch, "")
SUBAGENT(Explore, CExplore, "")
- SUBAGENT(MoveRelative, CMoveRelative, "")
+ SUBAGENT(CommandMoveRelative, CCommandMoveRelative, "")
+ SUBAGENT(ReportMove, CReportMove, "")
SUBAGENT(Halt, CHalt, "")
SUBAGENT(Follow, CFollow, "")
SUBAGENT(Pause, CPause, "")
@@ -452,7 +454,7 @@
DEFINE_AGENCY(CMoveCardinal,
DEFINE_CONCEPTS(
STRING_USER_CONCEPT(distance, "expl")
- STRING_USER_CONCEPT(direction, "expl")
+ STRING_USER_CONCEPT(direction, "expl")
STRING_SYSTEM_CONCEPT(report)
)
PRECONDITION(IS_TRUE(move_cardinal_command_issued)
@@ -470,27 +472,26 @@
)
//-----------------------------------------------------------------------------
-// /zap2/Task/MoveRelative
+// /zap2/Task/CommandMoveRelative
//-----------------------------------------------------------------------------
-DEFINE_AGENCY(CMoveRelative,
+DEFINE_AGENCY(CCommandMoveRelative,
DEFINE_CONCEPTS(
- STRING_USER_CONCEPT(direction, "expl")
+ STRING_USER_CONCEPT(direction, "expl")
STRING_USER_CONCEPT(distance, "expl")
STRING_USER_CONCEPT(units, "")
- STRING_SYSTEM_CONCEPT(report)
+ STRING_SYSTEM_CONCEPT(report)
)
PRECONDITION(IS_TRUE(move_relative_command_issued)
&& (UPDATED(distance) || UPDATED(direction)) &&
- (*C("current_addressee").CreateMergedHistoryConcept() == C("robot_name") ||
+ (*C("current_addressee").CreateMergedHistoryConcept() == C("robot_name") ||
*C("current_addressee").CreateMergedHistoryConcept() == C("everyone")))
DEFINE_SUBAGENTS(
SUBAGENT(ExpectMoveRelativeCommand, CExpectMoveRelativeCommand, "")
SUBAGENT(RequestMoveDirection, CRequestMoveDirection, "")
SUBAGENT(RequestRelativeDistance, CRequestRelativeDistance, "")
SUBAGENT(ExecuteRelativeMove, CExecuteRelativeMove, "")
- SUBAGENT(InformReaction2Move, CInformReaction2Move, "")
)
- SUCCEEDS_WHEN(COMPLETED(InformReaction2Move) || UPDATED_IN_LAST_TURN(cancel))
+ SUCCEEDS_WHEN(COMPLETED(ExecuteRelativeMove) || UPDATED_IN_LAST_TURN(cancel))
)
//-----------------------------------------------------------------------------
@@ -574,6 +575,37 @@
)
//-----------------------------------------------------------------------------
+// /zap2/Task/ReportMove
+//-----------------------------------------------------------------------------
+DEFINE_AGENCY(CReportMove,
+ PRECONDITION(UPDATED(move_report) &&
+ (*C("current_addressee").CreateMergedHistoryConcept() == C("robot_name") ||
+ *C("current_addressee").CreateMergedHistoryConcept() == C("everyone")))
+ DEFINE_SUBAGENTS(
+ SUBAGENT(ExpectReportMove, CExpectReportMove, "")
+ SUBAGENT(InformMove, CInformMove, "")
+ )
+)
+
+//-----------------------------------------------------------------------------
+// /zap2/Task/ReportMove/ExpectReportMove
+//-----------------------------------------------------------------------------
+DEFINE_EXPECT_AGENT(CExpectReportMove,
+ EXPECT_CONCEPT(move_report)
+ EXPECT_WHEN(
+ (*C("current_addressee").CreateMergedHistoryConcept() == C("robot_name") ||
+ *C("current_addressee").CreateMergedHistoryConcept() == C("everyone")))
+ GRAMMAR_MAPPING("[RobotMessage.Move]")
+)
+
+//-----------------------------------------------------------------------------
+// /zap2/Task/ReportMove/InformMove
+//-----------------------------------------------------------------------------
+DEFINE_INFORM_AGENT(CInformMove,
+ PROMPT("inform report_move_status <robot_name <move_report")
+)
+
+//-----------------------------------------------------------------------------
// /zap2/Task/Move/InformReaction2Move
//-----------------------------------------------------------------------------
DEFINE_INFORM_AGENT(CInformReaction2Move,
@@ -593,7 +625,7 @@
PRECONDITION(IS_TRUE(move_to_goal_command_issued) &&
(UPDATED(dir) || UPDATED(ordinal) || UPDATED(relDist)) &&
(*C("current_addressee").CreateMergedHistoryConcept() == C("robot_name") ||
- *C("current_addressee").CreateMergedHistoryConcept() == C("everyone")))
+ *C("current_addressee").CreateMergedHistoryConcept() == C("everyone")))
DEFINE_SUBAGENTS(
SUBAGENT(ExpectMoveToGoalCommand, CExpectMoveToGoalCommand, "")
SUBAGENT(ExpectRelDist, CExpectRelDist, "")
@@ -671,8 +703,8 @@
//-----------------------------------------------------------------------------
DEFINE_AGENCY(CSearch,
DEFINE_CONCEPTS(
- FLOAT_USER_CONCEPT(x1, "")
- FLOAT_USER_CONCEPT(x2, "")
+ FLOAT_USER_CONCEPT(x1, "")
+ FLOAT_USER_CONCEPT(x2, "")
FLOAT_USER_CONCEPT(x3, "")
FLOAT_USER_CONCEPT(x4, "")
FLOAT_USER_CONCEPT(x5, "")
@@ -681,8 +713,8 @@
FLOAT_USER_CONCEPT(x8, "")
FLOAT_USER_CONCEPT(x9, "")
FLOAT_USER_CONCEPT(x10, "")
- FLOAT_USER_CONCEPT(y1, "")
- FLOAT_USER_CONCEPT(y2, "")
+ FLOAT_USER_CONCEPT(y1, "")
+ FLOAT_USER_CONCEPT(y2, "")
FLOAT_USER_CONCEPT(y3, "")
FLOAT_USER_CONCEPT(y4, "")
FLOAT_USER_CONCEPT(y5, "")
@@ -696,7 +728,7 @@
PRECONDITION(IS_TRUE(search_command_issued) &&
(UPDATED(x1) && UPDATED(y1)) &&
(*C("current_addressee").CreateMergedHistoryConcept() == C("robot_name") ||
- *C("current_addressee").CreateMergedHistoryConcept() == C("everyone")))
+ *C("current_addressee").CreateMergedHistoryConcept() == C("everyone")))
DEFINE_SUBAGENTS(
SUBAGENT(ExpectSearchCommand, CExpectSearchCommand, "")
SUBAGENT(ExpectX1, CExpectX1, "")
@@ -2873,7 +2905,6 @@
DECLARE_AGENT(CQueryLocation)
DECLARE_AGENT(CExpectQueryLocationCommand)
DECLARE_AGENT(CExecuteGetLocation)
- // DECLARE_AGENT(CInformLocation)
DECLARE_AGENT(CReportLocation)
DECLARE_AGENT(CExpectReportLocationCommand)
DECLARE_AGENT(CInformLocation)
@@ -2883,11 +2914,14 @@
DECLARE_AGENT(CRequestCardinalDirection)
DECLARE_AGENT(CExecuteMove)
DECLARE_AGENT(CInformReaction2Move)
- DECLARE_AGENT(CMoveRelative)
+ DECLARE_AGENT(CCommandMoveRelative)
DECLARE_AGENT(CExpectMoveRelativeCommand)
DECLARE_AGENT(CRequestMoveDirection)
DECLARE_AGENT(CRequestRelativeDistance)
DECLARE_AGENT(CExecuteRelativeMove)
+ DECLARE_AGENT(CReportMove)
+ DECLARE_AGENT(CExpectReportMove)
+ DECLARE_AGENT(CInformMove)
DECLARE_AGENT(CMoveToGoal)
DECLARE_AGENT(CExpectMoveToGoalCommand)
DECLARE_AGENT(CExpectRelDist)
@@ -2957,7 +2991,7 @@
DECLARE_AGENT(CExecutePause)
DECLARE_AGENT(CInformPause)
DECLARE_AGENT(CContinue)
- DECLARE_AGENT(CExpectContinueCommand)
+ DECLARE_AGENT(CExpectContinueCommand)
DECLARE_AGENT(CExecuteContinue)
DECLARE_AGENT(CInformContinue)
DECLARE_AGENT(CTurn)
Modified: TeamTalk/Agents/TeamTalkNLG/Rosetta/TeamTalk/Inform.pm
===================================================================
--- TeamTalk/Agents/TeamTalkNLG/Rosetta/TeamTalk/Inform.pm 2007-02-25 14:08:57 UTC (rev 568)
+++ TeamTalk/Agents/TeamTalkNLG/Rosetta/TeamTalk/Inform.pm 2007-04-05 16:56:50 UTC (rev 569)
@@ -121,8 +121,9 @@
# verbal reaction to move command
"say_roger_that" => "Roger that!",
"report_move_to_goal" => "going to <ordinal>.",
-
"report_move_relative" => "going <direction> <distance> meters.",
+ "report_move" => ["This is <robot_name>. <move_report>",
+ "<robot_name> here. <move_report>"],
# verbal reaction to search command
"report_search" => "I am organizing a search party for the specified area.",
Modified: TeamTalk/Agents/boeingLib/boeing/boeing_net.h
===================================================================
--- TeamTalk/Agents/boeingLib/boeing/boeing_net.h 2007-02-25 14:08:57 UTC (rev 568)
+++ TeamTalk/Agents/boeingLib/boeing/boeing_net.h 2007-04-05 16:56:50 UTC (rev 569)
@@ -71,6 +71,7 @@
// standard status returns
+ static const int16_t ABORTED = -2;
static const int16_t FAILED = -1;
static const int16_t INPROGRESS = 0;
static const int16_t SUCCEEDED = 1;
Modified: TeamTalk/Agents/boeingLib/coralshared/win32dep.cc
===================================================================
--- TeamTalk/Agents/boeingLib/coralshared/win32dep.cc 2007-02-25 14:08:57 UTC (rev 568)
+++ TeamTalk/Agents/boeingLib/coralshared/win32dep.cc 2007-04-05 16:56:50 UTC (rev 569)
@@ -2,6 +2,8 @@
#include "win32dep.h"
+#include <cmath>
+
int gettimeofday (struct timeval *tv, void* tz)
{
union {
@@ -15,4 +17,13 @@
return (0);
}
+float round(float x) {
+ float major = floor(x);
+ float minor = x-major;
+ if(abs(minor >= 0.5))
+ if(major >=0) return major+1;
+ else return major-1;
+ else return major;
+}
+
#endif
Modified: TeamTalk/Agents/boeingLib/coralshared/win32dep.h
===================================================================
--- TeamTalk/Agents/boeingLib/coralshared/win32dep.h 2007-02-25 14:08:57 UTC (rev 568)
+++ TeamTalk/Agents/boeingLib/coralshared/win32dep.h 2007-04-05 16:56:50 UTC (rev 569)
@@ -11,6 +11,7 @@
#define sleep(x) Sleep(1000*(x))
int gettimeofday (struct timeval *tv, void* tz);
+float round(float x);
#define _USE_MATH_DEFINES
Modified: TeamTalk/Configurations/DesktopConfiguration/TeamTalk-hub-desktop-skeleton.pgm
===================================================================
--- TeamTalk/Configurations/DesktopConfiguration/TeamTalk-hub-desktop-skeleton.pgm 2007-02-25 14:08:57 UTC (rev 568)
+++ TeamTalk/Configurations/DesktopConfiguration/TeamTalk-hub-desktop-skeleton.pgm 2007-04-05 16:56:50 UTC (rev 569)
@@ -33,7 +33,7 @@
;; -------------------------------------------------
SERVER: PenDecoder at localhost:11002
-OPERATIONS: set_bot set_goal set_halt set_follow set_cover speak map_update image info_update task_update
+OPERATIONS: set_cover speak map_update info_update task_update
INIT: :greeting "Welcome to the CMU zap 2.0 PenDecoder!"
;; -------------------------------------------------
@@ -153,10 +153,6 @@
IN: :robot_name :x :y
OUT:
-RULE: :type = "image" --> PenDecoder.image
-IN: :robot_name :width :height :invoice :jpeg
-OUT:
-
PROGRAM: restart_decoder
RULE: --> sphinx.restart_decoder
IN:
Modified: TeamTalk/Configurations/DesktopConfiguration/TeamTalk-hub-desktop-template.pgm
===================================================================
--- TeamTalk/Configurations/DesktopConfiguration/TeamTalk-hub-desktop-template.pgm 2007-02-25 14:08:57 UTC (rev 568)
+++ TeamTalk/Configurations/DesktopConfiguration/TeamTalk-hub-desktop-template.pgm 2007-04-05 16:56:50 UTC (rev 569)
@@ -33,7 +33,7 @@
;; -------------------------------------------------
SERVER: PenDecoder at localhost:11002
-OPERATIONS: set_bot speak process_parse select_bot
+OPERATIONS: set_bot speak process_parse select_bot image set_goal
INIT: :greeting "Welcome to the %%DialogManager%%!"
;; -------------------------------------------------
@@ -240,7 +240,7 @@
OUT:
RULE: :type = "goal" --> PenDecoder.set_goal
-IN: :robot_name :relative :x :y
+IN: :robot_name :relative :x :y :status :taskid
OUT:
RULE: :type = "halt" --> PenDecoder.set_halt
@@ -248,11 +248,11 @@
OUT:
RULE: :type = "follow" --> PenDecoder.set_follow
-IN: :robot_name :followee
+IN: :robot_name :followee :status
OUT:
RULE: :type = "cover" --> PenDecoder.set_cover
-IN: :robot_name :x :y
+IN: :robot_name :x :y :status
OUT:
RULE: :type = "image" --> PenDecoder.image
More information about the TeamTalk-developers
mailing list